You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python读取SDF/MDL文件坐标:如何在遇到前两个空字符串行时停止读取?

Extracting Coordinate Data from SDF Files (MDL Format)

Got it, let's build a reusable function that reliably extracts the coordinate data from your SDF files, following the rules you laid out. Here's a clean, robust solution that works for any file of this format:

Complete Python Function

def extract_coordinates(sdf_file_path):
    coordinates = []
    collecting = False
    
    # Use 'with' to handle file I/O safely (auto-closes the file)
    with open(sdf_file_path, 'r') as file:
        for line in file:
            # Split line and filter out empty strings to handle variable spacing
            cleaned_parts = list(filter(None, line.strip().split()))
            
            # Check if we need to start collecting coordinate data
            # Coordinate lines have at least 4 elements: 3 numeric coords + atom symbol
            if not collecting and len(cleaned_parts) >= 4 and cleaned_parts[0].replace('.', '', 1).isdigit():
                collecting = True
                # Extract x, y, z (convert to float) and atom symbol
                x, y, z, atom = (float(cleaned_parts[0]), float(cleaned_parts[1]), 
                                 float(cleaned_parts[2]), cleaned_parts[3])
                coordinates.append((x, y, z, atom))
            
            # If we're already collecting, check for stop condition or continue
            elif collecting:
                # Stop when we hit a line starting with a digit (bond definition lines)
                if len(cleaned_parts) > 0 and cleaned_parts[0].isdigit():
                    collecting = False
                else:
                    # Add valid coordinate lines to our list
                    if len(cleaned_parts) >= 4:
                        x, y, z, atom = (float(cleaned_parts[0]), float(cleaned_parts[1]), 
                                         float(cleaned_parts[2]), cleaned_parts[3])
                        coordinates.append((x, y, z, atom))
    
    return coordinates

# Example usage with your ALA file
if __name__ == "__main__":
    ala_coords = extract_coordinates('ALA_model.sdf')
    print("Extracted coordinates:")
    for idx, coord in enumerate(ala_coords, 1):
        print(f"Atom {idx}: {coord[3]} at ({coord[0]:.4f}, {coord[1]:.4f}, {coord[2]:.4f})")

Key Details Explained

Let's break down how this handles your specific file structure:

  • Safe File Handling: The with statement ensures the file is automatically closed after processing, so you don't have to worry about resource leaks.
  • Cleaning Split Lines: Instead of dealing with messy lists full of empty strings (like your datasplit example), we use list(filter(None, line.strip().split())) to get only non-empty values. This simplifies pattern checking drastically.
  • Start Trigger: We start collecting when we encounter a line with at least 4 elements, where the first element is a numeric value (either integer or float). This correctly identifies the start of the coordinate section, no matter where it appears in the file.
  • Stop Trigger: Once collecting, we stop when we hit a line starting with a digit—these are the bond definition lines (like your datasplit[17] entry). This reliably marks the end of the coordinate data.
  • Data Extraction: For each valid coordinate line, we pull the first four values (x, y, z coordinates and atom symbol), convert the coordinates to floats, and store them as tuples for easy later use.

Testing the Function

When you run this with your ALA_model.sdf file, it will output all 13 atom coordinates exactly as expected, from the nitrogen atom down to the final hydrogen. And since it's a function, you can reuse it for any other SDF file of the same format without modifying the code.

内容的提问来源于stack exchange,提问作者PARCB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:57:46