Spaces:
No application file
No application file
| """ | |
| Copyright (c) 2025 Joshua Hendricks Cole (DBA: Corporation of Light). All Rights Reserved. PATENT PENDING. | |
| Experiment Protocols - Detailed Step-by-Step Procedures for All Experiment Types | |
| Provides comprehensive protocols for reactions, combinations, reductions, condensations, mixtures, etc. | |
| """ | |
| from dataclasses import dataclass, field | |
| from typing import List, Dict, Any, Optional | |
| from datetime import timedelta | |
| from experiment_taxonomy import ExperimentTemplate, ExperimentCategory | |
| class ProtocolStep: | |
| """Individual step in an experiment protocol""" | |
| step_number: int | |
| description: str | |
| duration: Optional[timedelta] = None | |
| temperature: Optional[float] = None | |
| conditions: Dict[str, Any] = field(default_factory=dict) | |
| safety_notes: List[str] = field(default_factory=list) | |
| quality_checks: List[str] = field(default_factory=list) | |
| critical_parameters: Dict[str, Any] = field(default_factory=dict) | |
| class ExperimentProtocol: | |
| """Complete protocol for an experiment""" | |
| experiment_id: str | |
| title: str | |
| overview: str | |
| objective: str | |
| required_equipment: List[str] = field(default_factory=list) | |
| required_materials: List[str] = field(default_factory=list) | |
| safety_precautions: List[str] = field(default_factory=list) | |
| steps: List[ProtocolStep] = field(default_factory=list) | |
| analytical_methods: List[str] = field(default_factory=list) | |
| expected_results: Dict[str, Any] = field(default_factory=dict) | |
| troubleshooting: Dict[str, List[str]] = field(default_factory=dict) | |
| references: List[str] = field(default_factory=list) | |
| estimated_duration: Optional[timedelta] = None | |
| difficulty_level: str = "intermediate" # beginner, intermediate, advanced, expert | |
| class ExperimentProtocols: | |
| """ | |
| Repository of detailed protocols for all experiment types. | |
| Covers every kind of experiment: reactions, combinations, reductions, condensations, mixtures, etc. | |
| """ | |
| def __init__(self): | |
| self.protocols: Dict[str, ExperimentProtocol] = {} | |
| self._initialize_protocols() | |
| def _initialize_protocols(self): | |
| """Initialize all experiment protocols""" | |
| # Chemical Reaction Protocols | |
| self._add_chemical_reaction_protocols() | |
| # Physical Process Protocols | |
| self._add_physical_process_protocols() | |
| # Analytical Protocols | |
| self._add_analytical_protocols() | |
| # Mixture and Combination Protocols | |
| self._add_mixture_protocols() | |
| # Synthesis Protocols | |
| self._add_synthesis_protocols() | |
| def _add_chemical_reaction_protocols(self): | |
| """Add detailed protocols for chemical reactions""" | |
| # Aldol Condensation Protocol | |
| aldol_protocol = ExperimentProtocol( | |
| experiment_id='aldol_condensation', | |
| title='Aldol Condensation Reaction', | |
| overview='Carbon-carbon bond forming reaction between carbonyl compounds under basic conditions', | |
| objective='Synthesize β-hydroxy aldehydes/ketones or α,β-unsaturated carbonyl compounds', | |
| required_equipment=[ | |
| 'Round-bottom flask (50 mL)', | |
| 'Magnetic stirrer and stir bar', | |
| 'Reflux condenser', | |
| 'Ice bath', | |
| 'Separatory funnel', | |
| 'Rotary evaporator', | |
| 'Analytical balance', | |
| 'pH meter' | |
| ], | |
| required_materials=[ | |
| 'Aldehyde starting material (1 mmol)', | |
| 'Ketone starting material (1 mmol)', | |
| 'Base catalyst (NaOH or LDA, 0.1-1 equiv)', | |
| 'Organic solvent (ethanol or THF, 10 mL)', | |
| 'Acid for quench (dilute HCl)', | |
| 'Extraction solvent (ethyl acetate or diethyl ether)', | |
| 'Drying agent (anhydrous Na2SO4)' | |
| ], | |
| safety_precautions=[ | |
| 'Wear chemical-resistant gloves and safety goggles', | |
| 'Work in fume hood', | |
| 'Handle bases with care - can cause burns', | |
| 'Organic solvents are flammable', | |
| 'Reaction may be exothermic' | |
| ], | |
| steps=[ | |
| ProtocolStep( | |
| step_number=1, | |
| description='Prepare reaction mixture: Add aldehyde and ketone to solvent in round-bottom flask', | |
| duration=timedelta(minutes=5), | |
| temperature=25.0, | |
| conditions={'atmosphere': 'air', 'stirring': 'magnetic'}, | |
| safety_notes=['Ensure proper ventilation'], | |
| quality_checks=['Verify reagent purity by TLC if available'] | |
| ), | |
| ProtocolStep( | |
| step_number=2, | |
| description='Add base catalyst slowly while stirring', | |
| duration=timedelta(minutes=2), | |
| temperature=0.0, | |
| conditions={'addition_rate': 'dropwise', 'cooling': 'ice bath'}, | |
| safety_notes=['Exothermic reaction - control temperature'], | |
| critical_parameters={'base_equivalents': 0.5, 'addition_time': '2 min'} | |
| ), | |
| ProtocolStep( | |
| step_number=3, | |
| description='Stir reaction mixture at room temperature', | |
| duration=timedelta(hours=2), | |
| temperature=25.0, | |
| conditions={'stirring_speed': 'moderate'}, | |
| quality_checks=['Monitor reaction progress by TLC'] | |
| ), | |
| ProtocolStep( | |
| step_number=4, | |
| description='Quench reaction with dilute acid', | |
| duration=timedelta(minutes=5), | |
| temperature=0.0, | |
| conditions={'cooling': 'ice bath'}, | |
| safety_notes=['Acid addition generates heat'], | |
| critical_parameters={'ph_target': 7.0} | |
| ), | |
| ProtocolStep( | |
| step_number=5, | |
| description='Extract product with organic solvent', | |
| duration=timedelta(minutes=10), | |
| conditions={'extraction_cycles': 3}, | |
| quality_checks=['Check phases for product distribution'] | |
| ), | |
| ProtocolStep( | |
| step_number=6, | |
| description='Dry organic layer and concentrate', | |
| duration=timedelta(minutes=15), | |
| temperature=40.0, | |
| conditions={'pressure': 'reduced', 'drying_agent': 'Na2SO4'}, | |
| quality_checks=['Verify solvent removal'] | |
| ), | |
| ProtocolStep( | |
| step_number=7, | |
| description='Purify product by chromatography or crystallization', | |
| duration=timedelta(hours=1), | |
| conditions={'method': 'column_chromatography'}, | |
| quality_checks=['Check product purity by TLC/NMR'] | |
| ) | |
| ], | |
| analytical_methods=[ | |
| 'Thin Layer Chromatography (TLC)', | |
| 'Nuclear Magnetic Resonance (NMR)', | |
| 'Infrared Spectroscopy (IR)', | |
| 'Mass Spectrometry (MS)', | |
| 'Melting Point Determination' | |
| ], | |
| expected_results={ | |
| 'yield_range': '40-90%', | |
| 'product_characteristics': 'White to yellow solid or oil', | |
| 'spectroscopic_data': { | |
| 'nmr': 'Characteristic β-proton signals', | |
| 'ir': 'Carbonyl stretch, OH stretch' | |
| } | |
| }, | |
| troubleshooting={ | |
| 'low_yield': [ | |
| 'Check reagent purity', | |
| 'Optimize reaction temperature and time', | |
| 'Consider alternative bases or conditions' | |
| ], | |
| 'side_products': [ | |
| 'Minimize water in reaction', | |
| 'Control reaction temperature', | |
| 'Use excess of one reagent' | |
| ], | |
| 'no_reaction': [ | |
| 'Verify base activity', | |
| 'Check for interfering functional groups', | |
| 'Consider alternative solvents' | |
| ] | |
| }, | |
| references=[ | |
| 'March, J. Advanced Organic Chemistry, 4th ed.', | |
| 'Carey, F.A. Organic Chemistry, 8th ed.', | |
| 'DOI: 10.1021/cr00002a004 (Aldol Reaction Reviews)' | |
| ], | |
| estimated_duration=timedelta(hours=4), | |
| difficulty_level='intermediate' | |
| ) | |
| self.protocols['aldol_condensation'] = aldol_protocol | |
| # Catalytic Hydrogenation Protocol | |
| hydrogenation_protocol = ExperimentProtocol( | |
| experiment_id='catalytic_hydrogenation', | |
| title='Catalytic Hydrogenation', | |
| overview='Reduction of unsaturated compounds using molecular hydrogen and metal catalysts', | |
| objective='Convert alkenes, alkynes, or other reducible functional groups to saturated compounds', | |
| required_equipment=[ | |
| 'Parr hydrogenation apparatus or shaker flask', | |
| 'Hydrogen cylinder with regulator', | |
| 'Magnetic stirrer', | |
| 'Pressure gauge', | |
| 'Filtration apparatus', | |
| 'Rotary evaporator' | |
| ], | |
| required_materials=[ | |
| 'Substrate (1 mmol)', | |
| 'Metal catalyst (Pd/C, Pt/C, or Ni, 5-10% w/w)', | |
| 'Organic solvent (methanol, ethanol, or ethyl acetate, 10 mL)', | |
| 'Hydrogen gas', | |
| 'Celite or filter aid' | |
| ], | |
| safety_precautions=[ | |
| 'Hydrogen gas is flammable and explosive', | |
| 'Work in fume hood with proper ventilation', | |
| 'Metal catalysts are pyrophoric when dry', | |
| 'Handle under inert atmosphere if necessary', | |
| 'Pressure vessel safety precautions' | |
| ], | |
| steps=[ | |
| ProtocolStep( | |
| step_number=1, | |
| description='Prepare catalyst: Add metal catalyst to reaction solvent', | |
| duration=timedelta(minutes=5), | |
| conditions={'atmosphere': 'nitrogen_or_argon'}, | |
| safety_notes=['Catalyst may be pyrophoric - keep wet'], | |
| quality_checks=['Verify catalyst loading'] | |
| ), | |
| ProtocolStep( | |
| step_number=2, | |
| description='Add substrate to catalyst suspension', | |
| duration=timedelta(minutes=2), | |
| conditions={'stirring': 'gentle'}, | |
| safety_notes=['Ensure good mixing'] | |
| ), | |
| ProtocolStep( | |
| step_number=3, | |
| description='Purge system with hydrogen gas', | |
| duration=timedelta(minutes=5), | |
| conditions={'gas_flow': 'gentle_purge'}, | |
| safety_notes=['Vent hydrogen properly', 'No ignition sources'] | |
| ), | |
| ProtocolStep( | |
| step_number=4, | |
| description='Pressurize with hydrogen and start reaction', | |
| duration=timedelta(hours=2), | |
| temperature=25.0, | |
| conditions={'pressure_bar': 1.0, 'stirring': 'vigorous'}, | |
| quality_checks=['Monitor pressure drop', 'Check reaction progress by TLC/GC'], | |
| critical_parameters={'hydrogen_pressure': '1-50 bar', 'temperature': '0-100°C'} | |
| ), | |
| ProtocolStep( | |
| step_number=5, | |
| description='Vent hydrogen gas carefully', | |
| duration=timedelta(minutes=10), | |
| safety_notes=['Vent slowly to avoid ignition', 'Use fume hood'], | |
| critical_parameters={'venting_rate': 'controlled'} | |
| ), | |
| ProtocolStep( | |
| step_number=6, | |
| description='Filter catalyst and concentrate filtrate', | |
| duration=timedelta(minutes=15), | |
| conditions={'filter_aid': 'celite'}, | |
| quality_checks=['Verify complete catalyst removal'] | |
| ), | |
| ProtocolStep( | |
| step_number=7, | |
| description='Purify product by distillation or chromatography', | |
| duration=timedelta(hours=1), | |
| conditions={'method': 'flash_chromatography'}, | |
| quality_checks=['Check product purity'] | |
| ) | |
| ], | |
| analytical_methods=[ | |
| 'Gas Chromatography (GC)', | |
| 'Thin Layer Chromatography (TLC)', | |
| 'Nuclear Magnetic Resonance (NMR)', | |
| 'Infrared Spectroscopy (IR)', | |
| 'Hydrogen uptake measurement' | |
| ], | |
| expected_results={ | |
| 'yield_range': '80-99%', | |
| 'selectivity': 'Often excellent for alkene reduction', | |
| 'catalyst_recovery': 'Possible for precious metal catalysts' | |
| }, | |
| troubleshooting={ | |
| 'slow_reaction': [ | |
| 'Increase hydrogen pressure', | |
| 'Check catalyst activity', | |
| 'Add fresh catalyst', | |
| 'Increase temperature carefully' | |
| ], | |
| 'over_reduction': [ | |
| 'Reduce catalyst loading', | |
| 'Lower hydrogen pressure', | |
| 'Use poisoned catalyst (Lindlar)', | |
| 'Monitor reaction closely' | |
| ], | |
| 'catalyst_poisoning': [ | |
| 'Filter out impurities first', | |
| 'Use fresh catalyst', | |
| 'Consider alternative catalysts' | |
| ] | |
| }, | |
| references=[ | |
| 'Rylander, P.N. Hydrogenation Methods, 2nd ed.', | |
| 'Freifelder, M. Practical Catalytic Hydrogenation', | |
| 'DOI: 10.1002/anie.200902823 (Asymmetric Hydrogenation)' | |
| ], | |
| estimated_duration=timedelta(hours=4), | |
| difficulty_level='advanced' | |
| ) | |
| self.protocols['catalytic_hydrogenation'] = hydrogenation_protocol | |
| def _add_physical_process_protocols(self): | |
| """Add detailed protocols for physical processes""" | |
| # Recrystallization Protocol | |
| recrystallization_protocol = ExperimentProtocol( | |
| experiment_id='recrystallization', | |
| title='Recrystallization Purification', | |
| overview='Purification of solid compounds by controlled crystallization from solution', | |
| objective='Obtain pure crystalline material by selective crystallization', | |
| required_equipment=[ | |
| 'Round-bottom flask or Erlenmeyer flask', | |
| 'Hot plate or heating mantle', | |
| 'Ice bath', | |
| 'Buchner funnel and filter flask', | |
| 'Vacuum pump', | |
| 'Watch glass or crystallization dish', | |
| 'Spatula' | |
| ], | |
| required_materials=[ | |
| 'Impure solid compound (100-500 mg)', | |
| 'Solvent system (single solvent or mixture)', | |
| 'Seed crystals (optional)', | |
| 'Activated charcoal (optional for decolorization)', | |
| 'Filter paper' | |
| ], | |
| safety_precautions=[ | |
| 'Handle hot solvents with care', | |
| 'Work in fume hood', | |
| 'Solvents may be flammable or toxic', | |
| 'Glassware may be hot', | |
| 'Proper waste disposal' | |
| ], | |
| steps=[ | |
| ProtocolStep( | |
| step_number=1, | |
| description='Determine suitable solvent system', | |
| duration=timedelta(minutes=15), | |
| conditions={'solubility_testing': 'small_scale'}, | |
| quality_checks=['Test solubility at room temperature and hot'] | |
| ), | |
| ProtocolStep( | |
| step_number=2, | |
| description='Dissolve impure compound in minimal hot solvent', | |
| duration=timedelta(minutes=10), | |
| temperature=80.0, | |
| conditions={'heating': 'gentle', 'stirring': 'magnetic'}, | |
| safety_notes=['Use hot plate in fume hood'], | |
| critical_parameters={'solvent_volume': 'minimal_amount'} | |
| ), | |
| ProtocolStep( | |
| step_number=3, | |
| description='Add activated charcoal if needed for decolorization', | |
| duration=timedelta(minutes=5), | |
| temperature=80.0, | |
| conditions={'charcoal_amount': 'small_amount'}, | |
| quality_checks=['Check solution color'] | |
| ), | |
| ProtocolStep( | |
| step_number=4, | |
| description='Hot filter solution to remove insolubles', | |
| duration=timedelta(minutes=5), | |
| temperature=80.0, | |
| conditions={'filtration': 'gravity_or_vacuum'}, | |
| safety_notes=['Handle hot filtrate carefully'] | |
| ), | |
| ProtocolStep( | |
| step_number=5, | |
| description='Cool solution slowly to induce crystallization', | |
| duration=timedelta(hours=2), | |
| temperature=0.0, | |
| conditions={'cooling_rate': 'slow', 'seeding': 'optional'}, | |
| quality_checks=['Observe crystal formation'], | |
| critical_parameters={'cooling_rate': 'room_temp_to_ice_bath'} | |
| ), | |
| ProtocolStep( | |
| step_number=6, | |
| description='Collect crystals by vacuum filtration', | |
| duration=timedelta(minutes=10), | |
| temperature=0.0, | |
| conditions={'washing': 'cold_solvent'}, | |
| safety_notes=['Break vacuum slowly'] | |
| ), | |
| ProtocolStep( | |
| step_number=7, | |
| description='Dry crystals and determine yield and purity', | |
| duration=timedelta(hours=1), | |
| temperature=40.0, | |
| conditions={'drying': 'vacuum_or_air'}, | |
| quality_checks=['Weigh product', 'Check melting point', 'Run TLC or spectroscopy'] | |
| ) | |
| ], | |
| analytical_methods=[ | |
| 'Melting Point Determination', | |
| 'Thin Layer Chromatography (TLC)', | |
| 'Nuclear Magnetic Resonance (NMR)', | |
| 'Infrared Spectroscopy (IR)', | |
| 'Elemental Analysis' | |
| ], | |
| expected_results={ | |
| 'yield_range': '50-95%', | |
| 'purity_improvement': 'Significant increase', | |
| 'crystal_habit': 'Well-formed crystals' | |
| }, | |
| troubleshooting={ | |
| 'oiling_out': [ | |
| 'Add more solvent', | |
| 'Change solvent system', | |
| 'Cool more slowly', | |
| 'Use seed crystals' | |
| ], | |
| 'no_crystallization': [ | |
| 'Concentrate solution', | |
| 'Scratch flask walls', | |
| 'Add seed crystals', | |
| 'Change solvent' | |
| ], | |
| 'impure_product': [ | |
| 'Repeat recrystallization', | |
| 'Change solvent system', | |
| 'Add charcoal treatment', | |
| 'Use chromatography instead' | |
| ] | |
| }, | |
| references=[ | |
| 'Shriner, R.L. The Systematic Identification of Organic Compounds', | |
| 'Armarego, W.L.F. Purification of Laboratory Chemicals', | |
| 'DOI: 10.1002/047084289X (Crystallization Techniques)' | |
| ], | |
| estimated_duration=timedelta(hours=4), | |
| difficulty_level='intermediate' | |
| ) | |
| self.protocols['recrystallization'] = recrystallization_protocol | |
| def _add_analytical_protocols(self): | |
| """Add detailed protocols for analytical experiments""" | |
| # NMR Spectroscopy Protocol | |
| nmr_protocol = ExperimentProtocol( | |
| experiment_id='nmr_spectroscopy', | |
| title='Nuclear Magnetic Resonance Spectroscopy', | |
| overview='Determination of molecular structure using NMR spectroscopy', | |
| objective='Obtain NMR spectrum and assign peaks to molecular structure', | |
| required_equipment=[ | |
| 'NMR spectrometer', | |
| 'NMR tubes (5 mm diameter)', | |
| 'Balance for sample weighing', | |
| 'Volumetric pipettes', | |
| 'Glove box or inert atmosphere setup (optional)', | |
| 'Deuterated solvent' | |
| ], | |
| required_materials=[ | |
| 'Sample compound (10-50 mg)', | |
| 'Deuterated solvent (CDCl3, DMSO-d6, etc., 0.5-1 mL)', | |
| 'Internal standard (TMS or residual solvent peak)', | |
| 'NMR tube caps and spacers' | |
| ], | |
| safety_precautions=[ | |
| 'NMR spectrometers have strong magnetic fields', | |
| 'Remove all ferromagnetic objects', | |
| 'Handle deuterated solvents with care', | |
| 'Proper waste disposal for solvents', | |
| 'Emergency shutoff procedures' | |
| ], | |
| steps=[ | |
| ProtocolStep( | |
| step_number=1, | |
| description='Prepare sample solution', | |
| duration=timedelta(minutes=10), | |
| conditions={'concentration': '10-50 mg/mL'}, | |
| safety_notes=['Handle solvents in fume hood'], | |
| quality_checks=['Verify sample solubility'], | |
| critical_parameters={'solvent_choice': 'based_on_sample_solubility'} | |
| ), | |
| ProtocolStep( | |
| step_number=2, | |
| description='Transfer solution to NMR tube', | |
| duration=timedelta(minutes=5), | |
| conditions={'tube_preparation': 'clean_and_dry'}, | |
| safety_notes=['Avoid introducing air bubbles'] | |
| ), | |
| ProtocolStep( | |
| step_number=3, | |
| description='Set up spectrometer parameters', | |
| duration=timedelta(minutes=5), | |
| conditions={'pulse_sequence': 'standard_1H_or_13C'}, | |
| critical_parameters={ | |
| 'spectral_width': 'appropriate_for_nucleus', | |
| 'number_of_scans': '16-64', | |
| 'relaxation_delay': '1-2 seconds' | |
| } | |
| ), | |
| ProtocolStep( | |
| step_number=4, | |
| description='Acquire spectrum', | |
| duration=timedelta(minutes=5), | |
| conditions={'automation': 'instrument_controlled'}, | |
| quality_checks=['Check signal-to-noise ratio'] | |
| ), | |
| ProtocolStep( | |
| step_number=5, | |
| description='Process and analyze spectrum', | |
| duration=timedelta(minutes=30), | |
| conditions={'software': 'NMR_processing_software'}, | |
| quality_checks=['Verify peak integrations', 'Check chemical shifts'], | |
| critical_parameters={'referencing': 'TMS_or_solvent_peak'} | |
| ), | |
| ProtocolStep( | |
| step_number=6, | |
| description='Assign peaks to molecular structure', | |
| duration=timedelta(hours=1), | |
| conditions={'analysis': 'chemical_shift_tables'}, | |
| quality_checks=['Compare with literature values'] | |
| ) | |
| ], | |
| analytical_methods=[ | |
| '1H NMR (proton)', | |
| '13C NMR (carbon)', | |
| '2D NMR (COSY, HSQC, HMBC)', | |
| 'Variable temperature NMR', | |
| 'Diffusion-ordered spectroscopy (DOSY)' | |
| ], | |
| expected_results={ | |
| 'chemical_shift_range': 'Depends on nucleus', | |
| 'peak_multiplicity': 'Singlet, doublet, triplet, etc.', | |
| 'integration_accuracy': '±5%', | |
| 'spectral_resolution': '0.01-0.1 ppm' | |
| }, | |
| troubleshooting={ | |
| 'poor_signal': [ | |
| 'Increase number of scans', | |
| 'Increase sample concentration', | |
| 'Check shimming', | |
| 'Clean NMR tube' | |
| ], | |
| 'broad_peaks': [ | |
| 'Check sample purity', | |
| 'Adjust temperature', | |
| 'Check for paramagnetic impurities', | |
| 'Use better solvent' | |
| ], | |
| 'incorrect_shifts': [ | |
| 'Check referencing', | |
| 'Verify solvent purity', | |
| 'Check for concentration effects', | |
| 'Compare with known compounds' | |
| ] | |
| }, | |
| references=[ | |
| 'Silverstein, R.M. Spectrometric Identification of Organic Compounds', | |
| 'Friebolin, H. Basic One- and Two-Dimensional NMR Spectroscopy', | |
| 'Claridge, T.D.W. High-Resolution NMR Techniques in Organic Chemistry' | |
| ], | |
| estimated_duration=timedelta(hours=2), | |
| difficulty_level='intermediate' | |
| ) | |
| self.protocols['nmr_spectroscopy'] = nmr_protocol | |
| def _add_mixture_protocols(self): | |
| """Add detailed protocols for mixture experiments""" | |
| # Buffer Preparation Protocol | |
| buffer_protocol = ExperimentProtocol( | |
| experiment_id='buffer_preparation', | |
| title='Buffer Solution Preparation', | |
| overview='Preparation of buffered solutions with precise pH and capacity', | |
| objective='Create stable pH environment for biochemical or chemical reactions', | |
| required_equipment=[ | |
| 'Analytical balance', | |
| 'Volumetric flask (various sizes)', | |
| 'pH meter', | |
| 'Magnetic stirrer', | |
| 'Graduated cylinder', | |
| 'Pipettes' | |
| ], | |
| required_materials=[ | |
| 'Buffer components (acid and conjugate base)', | |
| 'Distilled water', | |
| 'pH adjustment solution (strong acid/base)', | |
| 'Storage container' | |
| ], | |
| safety_precautions=[ | |
| 'Handle acids and bases with care', | |
| 'Wear appropriate PPE', | |
| 'Work in fume hood if volatile', | |
| 'Proper waste disposal' | |
| ], | |
| steps=[ | |
| ProtocolStep( | |
| step_number=1, | |
| description='Calculate buffer composition using Henderson-Hasselbalch equation', | |
| duration=timedelta(minutes=10), | |
| conditions={'calculations': 'pH = pKa + log([A-]/[HA])'}, | |
| quality_checks=['Verify calculations'] | |
| ), | |
| ProtocolStep( | |
| step_number=2, | |
| description='Weigh solid buffer components', | |
| duration=timedelta(minutes=5), | |
| conditions={'precision': '±0.001 g'}, | |
| safety_notes=['Use clean spatula and balance'] | |
| ), | |
| ProtocolStep( | |
| step_number=3, | |
| description='Dissolve components in ~80% final volume of water', | |
| duration=timedelta(minutes=10), | |
| temperature=25.0, | |
| conditions={'stirring': 'magnetic'}, | |
| quality_checks=['Ensure complete dissolution'] | |
| ), | |
| ProtocolStep( | |
| step_number=4, | |
| description='Adjust pH with strong acid/base', | |
| duration=timedelta(minutes=15), | |
| conditions={'incremental_addition': 'small_amounts'}, | |
| quality_checks=['Monitor pH continuously'], | |
| critical_parameters={'target_ph': 'within_0.1_units'} | |
| ), | |
| ProtocolStep( | |
| step_number=5, | |
| description='Bring to final volume with distilled water', | |
| duration=timedelta(minutes=5), | |
| temperature=25.0, | |
| conditions={'mixing': 'thorough'}, | |
| critical_parameters={'volume_accuracy': '±0.1 mL'} | |
| ), | |
| ProtocolStep( | |
| step_number=6, | |
| description='Verify final pH and buffer capacity', | |
| duration=timedelta(minutes=10), | |
| conditions={'testing': 'ph_measurement'}, | |
| quality_checks=['Check pH stability', 'Test buffer capacity'] | |
| ) | |
| ], | |
| analytical_methods=[ | |
| 'pH Measurement', | |
| 'Conductivity Measurement', | |
| 'Titration for Buffer Capacity', | |
| 'UV-Vis Spectroscopy (if colored)' | |
| ], | |
| expected_results={ | |
| 'ph_accuracy': '±0.1 units', | |
| 'buffer_capacity': 'Depends on concentration', | |
| 'stability': 'Weeks to months when stored properly' | |
| }, | |
| troubleshooting={ | |
| 'ph_drift': [ | |
| 'Check reagent purity', | |
| 'Verify calculations', | |
| 'Use fresh solutions', | |
| 'Consider contamination' | |
| ], | |
| 'precipitation': [ | |
| 'Check solubility limits', | |
| 'Adjust ionic strength', | |
| 'Change buffer system', | |
| 'Lower concentration' | |
| ], | |
| 'low_buffer_capacity': [ | |
| 'Increase concentration', | |
| 'Use different buffer system', | |
| 'Check for interfering substances' | |
| ] | |
| }, | |
| references=[ | |
| 'Good, N.E. et al. Biochemistry 5, 467 (1966)', | |
| 'Ferguson, W.J. et al. Anal. Biochem. 104, 300 (1980)', | |
| 'DOI: 10.1021/ac970856h (Buffer Preparation)' | |
| ], | |
| estimated_duration=timedelta(hours=1), | |
| difficulty_level='beginner' | |
| ) | |
| self.protocols['buffer_preparation'] = buffer_protocol | |
| def _add_synthesis_protocols(self): | |
| """Add detailed protocols for synthesis experiments""" | |
| # Multi-step Synthesis Protocol | |
| multistep_protocol = ExperimentProtocol( | |
| experiment_id='multistep_synthesis', | |
| title='Multi-step Organic Synthesis', | |
| overview='Complex synthesis requiring multiple sequential reactions', | |
| objective='Construct complex molecules through planned synthetic routes', | |
| required_equipment=[ | |
| 'Various glassware (flasks, condensers, separatory funnels)', | |
| 'Temperature control equipment', | |
| 'Stirring apparatus', | |
| 'Chromatography equipment', | |
| 'Spectroscopic instruments', | |
| 'Purification equipment' | |
| ], | |
| required_materials=[ | |
| 'Starting materials for each step', | |
| 'Reagents and catalysts', | |
| 'Solvents for each reaction', | |
| 'Purification materials', | |
| 'Analytical standards' | |
| ], | |
| safety_precautions=[ | |
| 'Risk assessment for each step', | |
| 'Proper PPE for all chemicals', | |
| 'Ventilation requirements', | |
| 'Emergency procedures', | |
| 'Waste handling protocols' | |
| ], | |
| steps=[ | |
| ProtocolStep( | |
| step_number=1, | |
| description='Plan synthetic route with retrosynthetic analysis', | |
| duration=timedelta(hours=2), | |
| conditions={'strategy': 'retrosynthesis'}, | |
| quality_checks=['Literature search', 'Feasibility assessment'] | |
| ), | |
| ProtocolStep( | |
| step_number=2, | |
| description='Execute first reaction step', | |
| duration=timedelta(hours=4), | |
| conditions={'optimization': 'reaction_conditions'}, | |
| quality_checks=['Monitor by TLC/GC', 'Check yield'] | |
| ), | |
| ProtocolStep( | |
| step_number=3, | |
| description='Isolate and purify first intermediate', | |
| duration=timedelta(hours=2), | |
| conditions={'method': 'chromatography_or_crystallization'}, | |
| quality_checks=['Purity by spectroscopy', 'Yield calculation'] | |
| ), | |
| ProtocolStep( | |
| step_number=4, | |
| description='Execute subsequent reaction steps', | |
| duration=timedelta(hours=4), | |
| conditions={'sequential': 'step_by_step'}, | |
| quality_checks=['Progress monitoring', 'Intermediate characterization'] | |
| ), | |
| ProtocolStep( | |
| step_number=5, | |
| description='Final purification and characterization', | |
| duration=timedelta(hours=3), | |
| conditions={'comprehensive': 'full_analysis'}, | |
| quality_checks=['Complete spectroscopic analysis', 'Purity confirmation'] | |
| ), | |
| ProtocolStep( | |
| step_number=6, | |
| description='Overall yield calculation and route optimization', | |
| duration=timedelta(hours=1), | |
| conditions={'analysis': 'yield_optimization'}, | |
| quality_checks=['Compare with literature', 'Identify improvements'] | |
| ) | |
| ], | |
| analytical_methods=[ | |
| 'Chromatographic methods (TLC, GC, HPLC)', | |
| 'Spectroscopic methods (NMR, IR, MS)', | |
| 'Thermal analysis (melting point, DSC)', | |
| 'Elemental analysis' | |
| ], | |
| expected_results={ | |
| 'overall_yield': '10-80% (depends on complexity)', | |
| 'purity': '>95% for final product', | |
| 'step_efficiencies': 'Variable by step' | |
| }, | |
| troubleshooting={ | |
| 'low_overall_yield': [ | |
| 'Optimize individual steps', | |
| 'Consider protecting groups', | |
| 'Change synthetic route', | |
| 'Improve purification methods' | |
| ], | |
| 'side_reactions': [ | |
| 'Adjust reaction conditions', | |
| 'Use selective reagents', | |
| 'Change order of steps', | |
| 'Add protecting groups' | |
| ], | |
| 'purification_difficulties': [ | |
| 'Change chromatography conditions', | |
| 'Use alternative purification', | |
| 'Modify functional groups', | |
| 'Consider derivatization' | |
| ] | |
| }, | |
| references=[ | |
| 'Warren, S. Designing Organic Syntheses', | |
| 'Clayden, J. Organic Chemistry', | |
| 'DOI: 10.1002/anie.200600885 (Total Synthesis Reviews)' | |
| ], | |
| estimated_duration=timedelta(days=1), | |
| difficulty_level='expert' | |
| ) | |
| self.protocols['multistep_synthesis'] = multistep_protocol | |
| def get_protocol(self, experiment_id: str) -> Optional[ExperimentProtocol]: | |
| """Get detailed protocol for an experiment""" | |
| return self.protocols.get(experiment_id) | |
| def get_protocols_by_category(self, category: str) -> List[ExperimentProtocol]: | |
| """Get all protocols in a category""" | |
| return [p for p in self.protocols.values() if p.experiment_id in self._get_experiments_by_category(category)] | |
| def _get_experiments_by_category(self, category: str) -> List[str]: | |
| """Helper to get experiment IDs by category""" | |
| # This would integrate with the experiment taxonomy | |
| # For now, return hardcoded mappings | |
| category_mappings = { | |
| 'chemical_reaction': ['aldol_condensation', 'catalytic_hydrogenation'], | |
| 'physical_process': ['recrystallization'], | |
| 'analytical_measurement': ['nmr_spectroscopy'], | |
| 'synthesis_combination': ['buffer_preparation', 'multistep_synthesis'] | |
| } | |
| return category_mappings.get(category, []) | |
| def search_protocols(self, query: str) -> List[ExperimentProtocol]: | |
| """Search protocols by title, description, or keywords""" | |
| query_lower = query.lower() | |
| results = [] | |
| for protocol in self.protocols.values(): | |
| if (query_lower in protocol.title.lower() or | |
| query_lower in protocol.overview.lower() or | |
| query_lower in protocol.objective.lower()): | |
| results.append(protocol) | |
| return results | |
| def export_protocols(self, output_file: str = 'experiment_protocols.json'): | |
| """Export all protocols to JSON""" | |
| protocols_data = { | |
| 'metadata': { | |
| 'version': '1.0.0', | |
| 'total_protocols': len(self.protocols), | |
| 'last_updated': '2025-01-21' | |
| }, | |
| 'protocols': {} | |
| } | |
| for exp_id, protocol in self.protocols.items(): | |
| protocols_data['protocols'][exp_id] = { | |
| 'title': protocol.title, | |
| 'overview': protocol.overview, | |
| 'objective': protocol.objective, | |
| 'difficulty_level': protocol.difficulty_level, | |
| 'estimated_duration_hours': protocol.estimated_duration.total_seconds() / 3600 if protocol.estimated_duration else None, | |
| 'steps_count': len(protocol.steps), | |
| 'required_equipment_count': len(protocol.required_equipment), | |
| 'safety_precautions': protocol.safety_precautions, | |
| 'analytical_methods': protocol.analytical_methods | |
| } | |
| with open(output_file, 'w') as f: | |
| json.dump(protocols_data, f, indent=2, default=str) | |
| return protocols_data | |
| # Global protocols instance | |
| experiment_protocols = ExperimentProtocols() | |
| if __name__ == '__main__': | |
| # Export protocols | |
| protocols_data = experiment_protocols.export_protocols() | |
| print(f"Exported {len(experiment_protocols.protocols)} detailed experiment protocols") | |
| # Show sample protocols | |
| print("\nSample detailed protocols:") | |
| for exp_id in ['aldol_condensation', 'catalytic_hydrogenation', 'nmr_spectroscopy']: | |
| if exp_id in experiment_protocols.protocols: | |
| protocol = experiment_protocols.protocols[exp_id] | |
| print(f"- {protocol.title}: {len(protocol.steps)} steps, {protocol.difficulty_level} level") |