当前位置: 首页 > news >正文

AI制药 - AlphaFold Multimer 的 MSA Pairing 源码

在这里插入图片描述

目前最新版本是v2.3.1,2023.1.12

  1. AlphaFold multimer v1 于 2021 年 7 月发布,同时发表了一篇描述其方法和结果的论文。AlphaFold multimer v1 使用了与 AlphaFold 单体相同的模型结构和训练方法,但增加了一些特征和损失函数来处理多条链。AlphaFold multimer v1 在几个蛋白质复合物的基准测试中取得了最先进的性能。

  2. AlphaFold multimer v2 于 2021 年 9 月 21 日发布,作为一个错误修复版本。AlphaFold multimer v2 没有改变模型参数或结构,但修复了松弛阶段的一些问题,并更新了一些第三方库。

  3. AlphaFold multimer v3 于 2021 年 12 月 3 日发布,带来了新的模型参数,预计在大型蛋白质复合物上更准确。AlphaFold multimer v3 使用了与 AlphaFold multimer v1 相同的模型结构和训练方法,但使用了不同的数据和超参数。AlphaFold multimer v3 还包括了一些内存优化和可用性改进。

入口函数:run_alphafold.py

调用逻辑:

def predict_structure(fasta_path: str,fasta_name: str,output_dir_base: str,data_pipeline: Union[pipeline.DataPipeline, pipeline_multimer.DataPipeline],model_runners: Dict[str, model.RunModel],amber_relaxer: relax.AmberRelaxation,benchmark: bool,random_seed: int):

其中,data_pipeline,选择pipeline_multimer.DataPipeline

  msa_output_dir = os.path.join(output_dir, 'msas')if not os.path.exists(msa_output_dir):os.makedirs(msa_output_dir)feature_dict = data_pipeline.process(input_fasta_path=fasta_path,msa_output_dir=msa_output_dir)

调用文件:pipeline_multimer.py,其中核心逻辑有三块:

  1. _process_single_chain,单链处理逻辑
  2. add_assembly_features,添加特征来区分不同的链
  3. pair_and_merge,配对合并MSA

源码及注释如下:

  def process(self,input_fasta_path: str,msa_output_dir: str) -> pipeline.FeatureDict:"""Runs alignment tools on the input sequences and creates features."""# 打开输入的fasta文件并读取内容with open(input_fasta_path) as f:input_fasta_str = f.read()# 解析fasta文件中的序列和描述信息input_seqs, input_descs = parsers.parse_fasta(input_fasta_str)# 根据序列和描述信息创建一个链ID的映射表chain_id_map = _make_chain_id_map(sequences=input_seqs,descriptions=input_descs)# 将链ID的映射表保存为json文件chain_id_map_path = os.path.join(msa_output_dir, 'chain_id_map.json')with open(chain_id_map_path, 'w') as f:chain_id_map_dict = {chain_id: dataclasses.asdict(fasta_chain)for chain_id, fasta_chain in chain_id_map.items()}json.dump(chain_id_map_dict, f, indent=4, sort_keys=True)# 初始化一个空字典来存储所有链的特征all_chain_features = {}# 初始化一个空字典来存储已经处理过的序列的特征,避免重复计算sequence_features = {}# 判断输入的序列是否是复合物或单体,即是否只有一种不同的序列is_homomer_or_monomer = len(set(input_seqs)) == 1# 遍历每个链ID和对应的fasta信息for chain_id, fasta_chain in chain_id_map.items():# 如果该链的序列已经在sequence_features中,直接复制其特征到all_chain_features中if fasta_chain.sequence in sequence_features:all_chain_features[chain_id] = copy.deepcopy(sequence_features[fasta_chain.sequence])continue# 否则,调用另一个函数来处理单个链,包括运行比对工具,生成特征等chain_features = self._process_single_chain(chain_id=chain_id,sequence=fasta_chain.sequence,description=fasta_chain.description,msa_output_dir=msa_output_dir,is_homomer_or_monomer=is_homomer_or_monomer)# 将单个链的特征转换为单体特征,即添加一些额外的信息,如链ID等chain_features = convert_monomer_features(chain_features, chain_id=chain_id)# 将单个链的特征添加到all_chain_features中all_chain_features[chain_id] = chain_features# 将单个链的特征添加到sequence_features中,以备后用sequence_features[fasta_chain.sequence] = chain_features# 为所有链的特征添加组装特征,即考虑多个链之间的相互作用等all_chain_features = add_assembly_features(all_chain_features)# 将所有链的特征进行配对和合并,得到一个numpy数组格式的样本np_example = feature_processing.pair_and_merge(all_chain_features=all_chain_features)# 将所有链的特征进行配对和合并,得到一个numpy数组格式的样本# Pad MSA to avoid zero-sized extra_msa.np_example = pad_msa(np_example, 512)# 返回最终的样本return np_example

其中,_process_single_chain的核心逻辑,如下:

  1. 调用self._monomer_data_pipeline.process(),生成单链的MSA信息
  2. 针对于多链,调用self._all_seq_msa_features

源码及注释如下:

  def _process_single_chain(self,chain_id: str,sequence: str,description: str,msa_output_dir: str,is_homomer_or_monomer: bool) -> pipeline.FeatureDict:"""Runs the monomer pipeline on a single chain."""# 为单个链生成fasta字符串chain_fasta_str = f'>chain_{chain_id}\n{sequence}\n'# 为单个链创建msa输出目录chain_msa_output_dir = os.path.join(msa_output_dir, chain_id)# 如果目录不存在,就创建它if not os.path.exists(chain_msa_output_dir):os.makedirs(chain_msa_output_dir)# 使用临时fasta文件运行单体数据流程with temp_fasta_file(chain_fasta_str) as chain_fasta_path:logging.info('Running monomer pipeline on chain %s: %s',chain_id, description)# 获取单个链的特征字典chain_features = self._monomer_data_pipeline.process(input_fasta_path=chain_fasta_path,msa_output_dir=chain_msa_output_dir)# 如果有两个或更多不同的序列,就构建配对特征# We only construct the pairing features if there are 2 or more unique# sequences.if not is_homomer_or_monomer:all_seq_msa_features = self._all_seq_msa_features(chain_fasta_path,chain_msa_output_dir)# 更新单个链的特征字典chain_features.update(all_seq_msa_features)# 返回单个链的特征字典return chain_features

其中,_all_seq_msa_features的核心逻辑,如下:

  • 额外添加MSA的物种信息,即msa_species_identifiers
  def _all_seq_msa_features(self, input_fasta_path, msa_output_dir):"""Get MSA features for unclustered uniprot, for pairing."""# 为未聚类的uniprot获取msa输出路径out_path = os.path.join(msa_output_dir, 'uniprot_hits.sto')# 运行msa工具,获取sto格式的结果result = pipeline.run_msa_tool(self._uniprot_msa_runner, input_fasta_path, out_path, 'sto',self.use_precomputed_msas)# 解析sto格式的结果,得到msa对象msa = parsers.parse_stockholm(result['sto'])# 截断msa对象,使其序列数不超过最大值msa = msa.truncate(max_seqs=self._max_uniprot_hits)# 从msa对象中提取特征all_seq_features = pipeline.make_msa_features([msa])# 筛选出有效的特征valid_feats = msa_pairing.MSA_FEATURES + ('msa_species_identifiers',  # MSA物种标识符)# 为特征添加前缀feats = {f'{k}_all_seq': v for k, v in all_seq_features.items()if k in valid_feats}# 返回特征字典return feats

其中,add_assembly_features的核心逻辑,如下:

  • 区分同源二聚体和异源二聚体,使用不同的链名标识。
  • 同时,添加不同的特征,用于区分同源和异源,如asym_id、sym_id、entity_id。
def add_assembly_features(all_chain_features: MutableMapping[str, pipeline.FeatureDict],) -> MutableMapping[str, pipeline.FeatureDict]:"""添加特征来区分不同的链。Args:all_chain_features: 一个字典,将链的id映射到每条链的特征字典。Returns:all_chain_features: 一个字典,将形式为`<seq_id>_<sym_id>`的字符串映射到相应的链特征。例如,一个同源二聚体的两条链会有键A_1和A_2。一个异源二聚体的两条链会有键A_1和B_1。"""# 按序列分组链# 创建一个空字典,用来存储序列和实体id的对应关系seq_to_entity_id = {}# 创建一个默认字典,用来按序列分组链的特征grouped_chains = collections.defaultdict(list)# 遍历所有链的特征for chain_id, chain_features in all_chain_features.items():# 获取链的序列seq = str(chain_features['sequence'])# 如果序列不在字典中,就给它分配一个新的实体idif seq not in seq_to_entity_id:seq_to_entity_id[seq] = len(seq_to_entity_id) + 1# 将链的特征添加到对应序列的列表中grouped_chains[seq_to_entity_id[seq]].append(chain_features)# 创建一个新的空字典,用来存储添加了新特征的链new_all_chain_features = {}# 初始化一个链的idchain_id = 1# 遍历按序列分组的链的特征for entity_id, group_chain_features in grouped_chains.items():# 遍历每个序列中的链,给它们分配一个对称idfor sym_id, chain_features in enumerate(group_chain_features, start=1):# 用实体id和对称id构造一个新的键,如A_1或B_2new_all_chain_features[f'{int_id_to_str_id(entity_id)}_{sym_id}'] = chain_features# 获取链的长度seq_length = chain_features['seq_length']# 添加不对称id,对称id和实体id作为特征chain_features['asym_id'] = chain_id * np.ones(seq_length)chain_features['sym_id'] = sym_id * np.ones(seq_length)chain_features['entity_id'] = entity_id * np.ones(seq_length)# 更新链的idchain_id += 1# 返回添加了新特征的链的字典return new_all_chain_features

其中,pair_and_merge的核心逻辑,如下:

  • process_unmerged_features,合并预处理。
  • create_paired_features,配对特征。
  • deduplicate_unpaired_sequences,移除与配对序列重复的未配对序列
  • merge_chain_features,合并链特征。
def pair_and_merge(all_chain_features: MutableMapping[str, pipeline.FeatureDict]) -> pipeline.FeatureDict:"""对特征进行增强、配对和合并的处理。Args:all_chain_features: 一个可变映射,存储每条链的特征字典。Returns:一个特征字典。"""# 对未合并的特征进行处理process_unmerged_features(all_chain_features)# 将所有链的特征转换为列表np_chains_list = list(all_chain_features.values())# 判断是否需要对MSA序列进行配对, _is_homomer_or_monomer中true是同源,false是异源# pair_msa_sequences表示异源pair_msa_sequences = not _is_homomer_or_monomer(np_chains_list)if pair_msa_sequences:  # 异源# 使用msa_pairing模块创建配对的特征np_chains_list = msa_pairing.create_paired_features(chains=np_chains_list)# 去除未配对的重复序列np_chains_list = msa_pairing.deduplicate_unpaired_sequences(np_chains_list)# 裁剪链的长度,限制MSA和模板的数量np_chains_list = crop_chains(np_chains_list,msa_crop_size=MSA_CROP_SIZE,pair_msa_sequences=pair_msa_sequences,max_templates=MAX_TEMPLATES)# 合并链的特征np_example = msa_pairing.merge_chain_features(np_chains_list=np_chains_list, pair_msa_sequences=pair_msa_sequences,max_templates=MAX_TEMPLATES)# 对最终的特征进行处理np_example = process_final(np_example)return np_example

其中,process_unmerged_features的核心逻辑,在chain_features中添加若干特征:

  • 包括deletion_matrix、deletion_matrix_all_seq、deletion_mean、all_atom_mask、all_atom_positions、entity_mask
  • 与多链相关的assembly_num_chains

源码如下:

def process_unmerged_features(all_chain_features: MutableMapping[str, pipeline.FeatureDict]):"""对合并前的每条链的特征进行后处理。"""num_chains = len(all_chain_features)for chain_features in all_chain_features.values():# 将删除矩阵转换为浮点数。chain_features['deletion_matrix'] = np.asarray(chain_features.pop('deletion_matrix_int'), dtype=np.float32)if 'deletion_matrix_int_all_seq' in chain_features:chain_features['deletion_matrix_all_seq'] = np.asarray(chain_features.pop('deletion_matrix_int_all_seq'), dtype=np.float32)# 计算删除矩阵的均值。chain_features['deletion_mean'] = np.mean(chain_features['deletion_matrix'], axis=0)# 根据aatype添加all_atom_mask和虚拟的all_atom_positions。all_atom_mask = residue_constants.STANDARD_ATOM_MASK[chain_features['aatype']]chain_features['all_atom_mask'] = all_atom_maskchain_features['all_atom_positions'] = np.zeros(list(all_atom_mask.shape) + [3])# 添加assembly_num_chains。chain_features['assembly_num_chains'] = np.asarray(num_chains)# 添加entity_mask。for chain_features in all_chain_features.values():chain_features['entity_mask'] = (chain_features['entity_id'] != 0).astype(np.int32)

其中,merge_chain_features,合并链特征:

  • 区分同源体,以及配对和不配对的特征合并。
def merge_chain_features(np_chains_list: List[pipeline.FeatureDict],pair_msa_sequences: bool,max_templates: int) -> pipeline.FeatureDict:"""将多条链的特征合并为单个FeatureDict.参数:np_chains_list: 每条链的FeatureDict的列表.pair_msa_sequences: 是否合并配对的MSA.max_templates: 包含的模板的最大数量.返回:整个复合物的单个FeatureDict."""# 对模板进行填充,使其数量不超过最大值np_chains_list = _pad_templates(np_chains_list, max_templates=max_templates)# 对同源体的密集MSA进行合并np_chains_list = _merge_homomers_dense_msa(np_chains_list)# 不配对的MSA特征将始终被分块对角化;配对的MSA特征将被连接.np_example = _merge_features_from_multiple_chains(np_chains_list, pair_msa_sequences=False)if pair_msa_sequences:# 将配对和不配对的特征连接起来np_example = _concatenate_paired_and_unpaired_features(np_example)# 根据合并后的特征进行修正np_example = _correct_post_merged_feats(np_example=np_example,np_chains_list=np_chains_list,pair_msa_sequences=pair_msa_sequences)return np_example

其中,create_paired_features的核心逻辑,主要步骤:

  1. 对链进行序列配对,得到配对的行索引:pair_sequences
  2. 对配对的行进行重新排序:reorder_paired_rows
  3. 特征填充:pad_features
def create_paired_features(chains: Iterable[pipeline.FeatureDict]) ->  List[pipeline.FeatureDict]:"""返回原始链的特征,其中包含配对的 NUM_SEQ 特征。Args:chains:  每条链的特征字典的列表。Returns:一个特征字典的列表,其中序列特征只包含要配对的行。"""chains = list(chains)chain_keys = chains[0].keys()if len(chains) < 2:return chainselse:updated_chains = []# 对链进行序列配对,得到配对的行索引paired_chains_to_paired_row_indices = pair_sequences(chains)# 对配对的行进行重新排序paired_rows = reorder_paired_rows(paired_chains_to_paired_row_indices)for chain_num, chain in enumerate(chains):# 创建一个新的链特征字典,不包含_all_seq后缀的特征new_chain = {k: v for k, v in chain.items() if '_all_seq' not in k}for feature_name in chain_keys:if feature_name.endswith('_all_seq'):# 对特征进行填充feats_padded = pad_features(chain[feature_name], feature_name)# 只保留配对的行new_chain[feature_name] = feats_padded[paired_rows[:, chain_num]]# 添加num_alignments_all_seq特征new_chain['num_alignments_all_seq'] = np.asarray(len(paired_rows[:, chain_num]))updated_chains.append(new_chain)return updated_chains

其中,pair_sequences的核心逻辑,主要根据物种配对MSA的信息,如下:

  • 根据序列相似度匹配MSA行:_match_rows_by_sequence_similarity
def pair_sequences(examples: List[pipeline.FeatureDict]) -> Dict[int, np.ndarray]:"""返回跨链配对的MSA序列的索引。"""num_examples = len(examples)# 创建一个列表,存储每条链的物种字典all_chain_species_dict = []# 创建一个集合,存储共同的物种common_species = set()for chain_features in examples:# 将链的特征转换为MSA数据框msa_df = _make_msa_df(chain_features)# 根据MSA数据框创建物种字典species_dict = _create_species_dict(msa_df)all_chain_species_dict.append(species_dict)# 将物种字典中的物种添加到共同物种集合中common_species.update(set(species_dict))# 对共同物种进行排序common_species = sorted(common_species)common_species.remove(b'')  # 移除目标序列的物种。# 创建一个列表,存储配对的MSA行all_paired_msa_rows = [np.zeros(len(examples), int)]# 创建一个字典,按照出现在多少条链中分组配对的MSA行all_paired_msa_rows_dict = {k: [] for k in range(num_examples)}all_paired_msa_rows_dict[num_examples] = [np.zeros(len(examples), int)]# 遍历共同物种for species in common_species:if not species:continue# 创建一个列表,存储每条链中该物种的MSA数据框this_species_msa_dfs = []# 记录该物种出现在多少条链中species_dfs_present = 0for species_dict in all_chain_species_dict:if species in species_dict:this_species_msa_dfs.append(species_dict[species])species_dfs_present += 1else:this_species_msa_dfs.append(None)# 跳过只出现在一条链中的物种if species_dfs_present <= 1:continue# 跳过MSA数据框过大的物种if np.any(np.array([len(species_df) for species_df inthis_species_msa_dfs ifisinstance(species_df, pd.DataFrame)]) > 600):continue# 根据序列相似度匹配MSA行paired_msa_rows = _match_rows_by_sequence_similarity(this_species_msa_dfs)# 将匹配的MSA行添加到列表和字典中all_paired_msa_rows.extend(paired_msa_rows)all_paired_msa_rows_dict[species_dfs_present].extend(paired_msa_rows)# 将字典中的值转换为数组all_paired_msa_rows_dict = {num_examples: np.array(paired_msa_rows) fornum_examples, paired_msa_rows in all_paired_msa_rows_dict.items()}return all_paired_msa_rows_dict

其中,_match_rows_by_sequence_similarity的核心逻辑:

def _match_rows_by_sequence_similarity(this_species_msa_dfs: List[pd.DataFrame]) -> List[List[int]]:"""根据序列相似度找出跨链的MSA序列配对。首先,将每条链的MSA序列按照它们与各自目标序列的相似度进行排序。然后,从最相似的序列开始进行配对。Args:this_species_msa_dfs: 一个列表,包含了特定物种的MSA特征的数据框。Returns:一个列表的列表,每个列表包含M个索引,对应于配对的MSA行,其中M是链的数量。"""all_paired_msa_rows = []# 获取每个数据框中的序列数量num_seqs = [len(species_df) for species_df in this_species_msa_dfsif species_df is not None]# 取最小的序列数量take_num_seqs = np.min(num_seqs)# 定义一个函数,按照相似度对数据框进行排序sort_by_similarity = (lambda x: x.sort_values('msa_similarity', axis=0, ascending=False))for species_df in this_species_msa_dfs:if species_df is not None:# 对该物种的数据框进行排序species_df_sorted = sort_by_similarity(species_df)# 获取前take_num_seqs个MSA行的索引msa_rows = species_df_sorted.msa_row.iloc[:take_num_seqs].valueselse:# 如果该物种不存在,则取最后一行(填充行)的索引msa_rows = [-1] * take_num_seqs  all_paired_msa_rows.append(msa_rows)# 将所有链的MSA行索引转置all_paired_msa_rows = list(np.array(all_paired_msa_rows).transpose())return all_paired_msa_rows

其中,deduplicate_unpaired_sequences的核心逻辑:

def deduplicate_unpaired_sequences(np_chains: List[pipeline.FeatureDict]) -> List[pipeline.FeatureDict]:"""移除与配对序列重复的未配对序列。"""# 获取特征的名称feature_names = np_chains[0].keys()# 获取MSA相关的特征msa_features = MSA_FEATURESfor chain in np_chains:# 将msa_all_seq特征转换为元组,方便哈希sequence_set = set(tuple(s) for s in chain['msa_all_seq'])keep_rows = []# 遍历未配对的MSA序列,移除任何与已配对序列相同的行for row_num, seq in enumerate(chain['msa']):if tuple(seq) not in sequence_set:keep_rows.append(row_num)# 更新MSA相关的特征,只保留需要的行for feature_name in feature_names:if feature_name in msa_features:chain[feature_name] = chain[feature_name][keep_rows]# 更新num_alignments特征chain['num_alignments'] = np.array(chain['msa'].shape[0], dtype=np.int32)return np_chains

其中,reorder_paired_rows的核心逻辑:

  • 创建一个包含跨链配对MSA行的索引列表.
  • 对配对链的数量进行降序遍历
def reorder_paired_rows(all_paired_msa_rows_dict: Dict[int, np.ndarray]) -> np.ndarray:"""创建一个包含跨链配对MSA行的索引列表.参数:all_paired_msa_rows_dict: 一个映射,从配对链的数量到配对索引.返回:一个列表的列表,每个列表包含跨链配对MSA行的索引.配对索引列表按以下顺序排序:1) 配对比对中的链的数量,即,所有链的配对将排在前面.2) e值"""# 初始化一个空列表all_paired_msa_rows = []# 对配对链的数量进行降序遍历for num_pairings in sorted(all_paired_msa_rows_dict, reverse=True):# 获取当前数量的配对索引paired_rows = all_paired_msa_rows_dict[num_pairings]# 计算每个配对索引的乘积的绝对值paired_rows_product = abs(np.array([np.prod(rows) for rows in paired_rows]))# 按照乘积的大小进行升序排序paired_rows_sort_index = np.argsort(paired_rows_product)# 将排序后的配对索引添加到列表中all_paired_msa_rows.extend(paired_rows[paired_rows_sort_index])# 将列表转换为数组并返回return np.array(all_paired_msa_rows)

相关文章:

AI制药 - AlphaFold Multimer 的 MSA Pairing 源码

目前最新版本是v2.3.1&#xff0c;2023.1.12 AlphaFold multimer v1 于 2021 年 7 月发布&#xff0c;同时发表了一篇描述其方法和结果的论文。AlphaFold multimer v1 使用了与 AlphaFold 单体相同的模型结构和训练方法&#xff0c;但增加了一些特征和损失函数来处理多条链。Al…...

TitanIDE:云原生开发到底强在哪里?

原文作者&#xff1a;行云创新技术总监 邓冰寒 引言 是一种新的软件开发方法&#xff0c;旨在构建更可靠、高效、弹性、安全和可扩展的应用程序。与传统的应用程序开发方式不同&#xff0c;云原生是将开发环境完全搬到云端&#xff0c;构建一站式的云原生开发环境。云原生的开…...

单片机常用完整性校验算法

一、前言 单片机在开发过程中经常会遇到大文件传输&#xff0c;或者大量数据传输&#xff0c;在一些工业环境下&#xff0c;数据传输并不是很稳定&#xff0c;如何检验数据的完整性就是个问题&#xff0c;这里简单介绍一下单片机常用的几种数据完整性校验方法。 二、CheckSum校…...

Anaconda 的安装配置及依赖项的内外网配置

在分享anaconda 的安装配置及使用前&#xff0c;我们必须先明白anaconda是什么&#xff1b;Anaconda是一个开源的Python发行版本。两者区别在于前者是一门编程语言&#xff0c;后者相当于编程语言中的工具包。 由于python自身缺少numpy、matplotlib、scipy、scikit-learn等一系…...

p84 CTF夺旗-PHP弱类型异或取反序列化RCE

数据来源 文章参考 本课重点&#xff1a; 案例1&#xff1a;PHP-相关总结知识点-后期复现案例2&#xff1a;PHP-弱类型对比绕过测试-常考点案例3&#xff1a;PHP-正则preg_match绕过-常考点案例4&#xff1a;PHP-命令执行RCE变异绕过-常考点案例5&#xff1a;PHP-反序列化考题…...

2022财报逆转,有赞穿透迷雾实现突破

2022年&#xff0c;商家经营面临困难。但在一些第三方服务商的帮助下&#xff0c;也有商家取得了逆势增长。 2023年3月23日&#xff0c;有赞发布2022年业绩报告&#xff0c;它帮助许多商家稳住了一整年的经营。2022年&#xff0c;有赞门店SaaS业务的GMV达到425亿元&#xff0c…...

蓝桥杯 - 求组合数【C(a,b)】+ 卡特兰数

文章目录&#x1f4ac;前言885. 求组合数 I C(m,n) 【dp】886 求组合数 II 【数据大小10万级别】 【费马小定理快速幂逆元】887. 求组合数 III 【le18级别】 【卢卡斯定理 逆元 快速幂 】888.求组合数 IV 【没有%p -- 高精度算出准确结果】 【分解质因数 高精度乘法 --只用一…...

膳食真菌在癌症免疫治疗中的作用: 从肠道微生物群的角度

谷禾健康 癌症是一种恶性肿瘤&#xff0c;它可以发生在人体的任何部位&#xff0c;包括肺、乳房、结肠、胃、肝、宫颈等。根据世界卫生组织的数据&#xff0c;全球每年有超过1800万人被诊断出患有癌症&#xff0c;其中约有1000万人死于癌症。癌症已成为全球范围内的主要健康问题…...

怎么将模糊的照片变清晰

怎么将模糊的照片变清晰?珍贵的照片每个人都会有&#xff0c;而遇到珍贵的照片变模糊了&#xff0c;相信会让人很苦恼的。那么有没有办法可以解决呢?答案是有的&#xff0c;我们可以用工具让模糊的照片变得清晰。下面就来分享一些让模糊的照片变清晰的方法&#xff0c;有兴趣…...

【软件测试】基础知识第一篇

文章目录一. 什么是软件测试二. 测试和调试的区别三. 什么是测试用例四. 软件的生命周期五. 软件测试的生命周期一. 什么是软件测试 软件测试就是验证软件产品特性是否满足用户的需求。 那需求又是什么呢&#xff1f;在多数软件公司&#xff0c;会有两种需求&#xff0c;一种…...

【百面成神】java web基础7问,你能坚持到第几问

前 言 &#x1f349; 作者简介&#xff1a;半旧518&#xff0c;长跑型选手&#xff0c;立志坚持写10年博客&#xff0c;专注于java后端 ☕专栏简介&#xff1a;纯手打总结面试题&#xff0c;自用备用 &#x1f330; 文章简介&#xff1a;java web最基础、重要的8道面试题 文章目…...

Centos7安装、各种环境配置和常见bug解决方案,保姆级教程(更新中)

文章目录前言一、Centos7安装二、各种环境配置与安装2.1 安装net-tools&#xff08;建议&#xff09;2.2 配置静态网络&#xff08;建议&#xff09;2.1 修改Centos7的时间&#xff08;建议&#xff09;2.2 Centos7系统编码问题2.3 vim安装&#xff08;建议&#xff09;2.4 解决…...

【C++进阶】智能指针

文章目录为什么需要智能指针&#xff1f;内存泄漏什么是内存泄漏&#xff0c;内存泄漏的危害内存泄漏分类&#xff08;了解&#xff09;如何避免内存泄漏智能指针的使用及原理smart_ptrauto_ptrunique_ptrshared_ptr线程安全的解决循环引用weak_ptr删除器为什么需要智能指针&am…...

软件测试面试题 —— 整理与解析(3)

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;&#x1f30e;【Austin_zhai】&#x1f30f; &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xf…...

springboot常用的20个注解

Spring Boot方式的项目开发已经逐步成为Java应用开发领域的主流框架&#xff0c;它不仅可以方便地创建生产级的Spring应用程序&#xff0c;还能轻松地通过一些注解配置与目前比较火热的微服务框架SpringCloud集成&#xff0c; 而Spring Boot 之所以能够轻松地实现应的创建及与…...

USB组合设备——带鼠标功能的键盘

文章目录带鼠标功能的键盘一个接口实现报告描述符示例多个接口实现复合设备和组合设备配置描述符集合的实现报告的返回附 STM32 枚举日志复合设备&#xff1a;Compound Device 内嵌 Hub 和多个 Function&#xff0c;每个 Function 都相当于一个独立的 USB 外设&#xff0c;有自…...

数据结构与算法基础-学习-18-哈夫曼编码

一、个人理解在远程通讯中&#xff0c;需要把字符转成二进制的字符串进行传输&#xff0c;例如我们需要传输ABCD&#xff0c;我们可以用定长的字符串进行表示&#xff0c;例如:A:00B:01C:02D:03这样可能就造成空间的浪费&#xff0c;我们多存储了一个0号位。那用变长呢&#xf…...

ZMC408CE | 实现“8通道独立PSO”应用场景

一、ZMC408SCAN产品亮点 1.高性能处理器&#xff0c;提升运算速度、响应时间和扫描周期等&#xff1b; 2.一维/二维/三维、多通道视觉飞拍&#xff0c;高速高精&#xff1b; 3.位置同步输出PSO&#xff0c;连续轨迹加工中对精密点胶胶量控制和激光能量控制等&#xff1b; 4…...

QuickJS中JS_SetClassProto方法把JavaScript对象指定为某个类的原型对象

在 QuickJS 中&#xff0c;JS_SetClassProto 方法用于设置一个类的原型对象。这个方法的作用是将一个 JavaScript 对象指定为该类的原型对象&#xff0c;从而定义该类的属性和方法。 具体来说&#xff0c;JS_SetClassProto 方法的第一个参数是指向 QuickJS 引擎执行上下文的指…...

泰克信号发生器特点

泰克信号发生器是一种用于产生各种类型的电子信号的仪器&#xff0c;可以广泛应用于电子、通信、自动化、医疗等领域。泰克信号发生器具有以下特点&#xff1a;多种信号类型&#xff1a;泰克信号发生器可以产生多种类型的电子信号&#xff0c;包括正弦波、方波、三角波、脉冲等…...

贯穿设计模式第四话--里氏替换原则

&#x1f973;&#x1f973;&#x1f973; 茫茫人海千千万万&#xff0c;感谢这一刻你看到了我的文章&#xff0c;感谢观赏&#xff0c;大家好呀&#xff0c;我是最爱吃鱼罐头&#xff0c;大家可以叫鱼罐头呦~&#x1f973;&#x1f973;&#x1f973; 从今天开始&#xff0c;将…...

6501: 鸡兔同笼

描述 一个笼子里面关了鸡和免子(鸡有两只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物&#xff0c;至多有多少只动物。 输入 一个正整数a(a<32768)。 输出 包含两个正整数&#xff0c;第一个是最少的动物数&#xff0c;第二个是最多的…...

Linux项目自动化构建工具-make/makefile 介绍及使用

使用背景 在工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义一系列 规则来指定什么文件需要先编译&#xff0c;什么文件需要后编译&#xff0c;哪些文件需要重新编译&#xff0c;或者更复杂 的功能操作 makefile带来的好处…...

【云原生|Docker】06-dokcerfile详解

目录 前言 Dockerfile基础示例 Dockerfile简介 1. Dockerfile概念 2. Dokcer镜像分层理解 ​3. Doker build构建原理 Dockerfile参数解析 1. Dokcerfile组成 2. 指令说明 2.1 FROM引入基础镜像 2.2 LABEL 2.3 ENV 2.4 RUN 2.5 COPY 2.6 ADD 2…...

【SCL】博图——先入先出排序法

使用博图SCL语言来实现先入先出排序 前言 使用SCL完成一个先入先出排序 具体要求&#xff1a;最先输入的一个数值&#xff0c;最先输出出来&#xff0c;下面的数自动向前填充&#xff1b; 注&#xff1a;这里可能有两种理解&#xff1a;一是第一个输入的第一个出来&#xff…...

OSPF----特殊区域

目录 OSPF----特殊区域 第一大类----末梢区域&#xff08;Stub Area&#xff09; 完全末梢区域&#xff08;(Totally Stub Area) 第二大类特殊区域----非完全末梢区域&#xff08;NSSA&#xff09; OSPF----特殊区域 第一大类----末梢区域&#xff08;Stub Area&#xff09…...

JVM-类加载

1&#xff1a;类加载机制&#xff1a; 加、验、准、解、初、使、卸 加、烟、准、姐、初、湿、鞋 加载、将class 文件转化为二进制流加载 JVM 内存中并生成一个该类的Class对象验证、Class 文件的字节流中包含的信息是否符合当前虚拟机的要求准备、在方法区中分配这些变量所…...

超详细讲解C语言文件操作!!

超详细讲解C语言文件操作&#xff01;&#xff01;什么是文件文件名文件的打开和关闭文件指针文件的打开和关闭文件的顺序读写文件的随机读写fseekftellrewind文本文件和二进制文件文件读取结束的判定文件缓冲区什么是文件 磁盘上的文件是文件。但是在程序设计中&#xff0c;我…...

linxu学习之进程

文章目录进程程序和进程产生进程销毁进程多进程高并发设计孤儿僵尸守护进程孤儿进程&#xff1a;守护进程(重点)僵尸进程&#xff1a;进程 程序和进程 操作系统可以运行多个程序&#xff0c;那他是如何运行的&#xff1f;实际上&#xff0c;CPU的执行是很快的&#xff0c;而待…...

蓝桥杯真题2

[蓝桥杯 2013 省 B] 连号区间数 题目描述 小明这些天一直在思考这样一个奇怪而有趣的问题&#xff1a; 在 111 ~ NNN 的某个全排列中有多少个连号区间呢&#xff1f;这里所说的连号区间的定义是&#xff1a; 如果区间 [L,R][L, R][L,R] 里的所有元素&#xff08;即此排列的…...

企业网站建设的重要性及意义/公关公司排名

目录 1、二进制和八进制表示法 2、Number.isFinite()、 Number.isNaN() 3、Number.parseInt() Number.parseFloat() 4、Number.isInteger() 5、Math对象的扩展 1、Math.trunc() 2、Math.sign() 3、Math.cbrt() 6、指数运算符 1、二进制和八进制表示法 ES6 提供了二进…...

青岛网站建设最便宜/广告联盟推广

了解如何使您的 Flutter 应用程序可靠且错误最少&#xff0c;并通过提高代码效率来减少重复调试。 在本文中&#xff0c;我将描述在您的 Flutter 项目中实现测试驱动开发 (TDD) 的步骤&#xff0c;并介绍该主题的基本介绍。 什么是 TDD&#xff1f; TDD 或测试驱动开发是在实…...

微网站开发 课程标准/整站关键词快速排名

导读据外媒报道&#xff0c;最新的 iOS 11 测试版又泄露天机了&#xff0c;开发人员发现苹果准备为 Apple Watch 加入更多锻炼模式&#xff0c;其中还包括复杂的跆拳道、垂钓和马术等。 据外媒报道&#xff0c;最新的 iOS 11 测试版又泄露天机了&#xff0c;开发人员发现苹果准…...

密云广州网站建设/百度竞价投放

...

网站建设项目描述范文/百度如何收录网站

解决微信浏览器内video全屏问题参考文章&#xff1a; &#xff08;1&#xff09;解决微信浏览器内video全屏问题 &#xff08;2&#xff09;https://www.cnblogs.com/phpjinggege/p/8270742.html 备忘一下。...

全屋定制设计培训哪里有/惠州seo代理计费

国家超算无锡中心近日发布“无锡超算云平台”&#xff0c;并宣布设立10个产业化平台&#xff0c;打造世界一流的超算技术与产业发展深度融合的高性能计算应用生态圈。 “无锡超算云平台”是一个以国家超算无锡中心为基础的高性能计算应用通用云桌面系统。国家超算无锡中心主任杨…...