Hydrogen atom types are assigned based on their parent types. The mmff-symb-mapping file
provides this mapping.

@param hdefIn input stream of mmff-symb-mapping.tsv
@return mapping of parent to hydrogen definitions
@throws IOException
966379
private Map<String, String> loadHydrogenDefinitions(InputStream hdefIn) throws IOException {

        // maps of symbolic atom types to hydrogen atom types and internal types
        final Map<String, String> hdefs = new HashMap<String, String>(200);

        BufferedReader br = new BufferedReader(new InputStreamReader(hdefIn));
        br.readLine(); // header
        String line = null;
        while ((line = br.readLine()) != null) {
            String[] cols = line.split("\t");
            hdefs.put(cols[0].trim(), cols[3].trim());
        }

        // these associations list hydrogens that are not listed in MMFFSYMB.PAR but present in MMFFHDEF.PAR
        // N=O HNO, NO2 HNO2, F HX, I HX, ONO2 HON, BR HX, ON=O HON, CL HX, SNO HSNO, and OC=S HOCS

        return hdefs;
    }
760272
public int calculateNumberOfImplicitHydrogens(IAtom atom, double bondOrderSum, IBond.Order maxBondOrder,
            int neighbourCount) throws CDKException {

        int missingHydrogens = 0;
        if (atom instanceof IPseudoAtom) {
            logger.debug("don't figure it out... it simply does not lack H's");
            return 0;
        }

        logger.debug("Calculating number of missing hydrogen atoms");
        // get default atom
        IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol());
        if (atomTypes.length == 0) {
            logger.warn("Element not found in configuration file: ", atom);
            return 0;
        }

        logger.debug("Found atomtypes: ", atomTypes.length);
        for (int f = 0; f < atomTypes.length; f++) {
            IAtomType type = atomTypes[f];
            if (couldMatchAtomType(atom, bondOrderSum, maxBondOrder, type)) {
                logger.debug("This type matches: ", type);
                int formalNeighbourCount = type.getFormalNeighbourCount();
                if (type.getHybridization() == CDKConstants.UNSET) {
                    missingHydrogens = (int) (type.getBondOrderSum() - bondOrderSum);
                } else if (type.getHybridization() == Hybridization.SP3) {
                    missingHydrogens = formalNeighbourCount - neighbourCount;
                } else if (type.getHybridization() == Hybridization.SP2) {
                    missingHydrogens = formalNeighbourCount - neighbourCount;
                } else if (type.getHybridization() == Hybridization.SP1) {
                    missingHydrogens = formalNeighbourCount - neighbourCount;
                } else {
                    missingHydrogens = (int) (type.getBondOrderSum() - bondOrderSum);
                }
                break;
            }
        }

        logger.debug("missing hydrogens: ", missingHydrogens);
        return missingHydrogens;
    }
425390
public boolean addRef(Object object)
        throws IOException
    {
        if (_refs == null)
            _refs = new IdentityHashMap();

        Integer ref = (Integer) _refs.get(object);

        if (ref != null) {
            int value = ref.intValue();

            writeRef(value);
            return true;
        }
        else {
            _refs.put(object, new Integer(_refs.size()));

            return false;
        }
    }
1007465
@Override
    public List<IAtomType> readAtomTypes(IChemObjectBuilder builder) throws IOException {
        List<IAtomType> atomTypes;
        if (ins == null) throw new IOException("There was a problem getting an input stream");
        OWLAtomTypeReader reader = new OWLAtomTypeReader(new InputStreamReader(ins));
        atomTypes = reader.readAtomTypes(builder);
        for (IAtomType atomType : atomTypes) {
            if (atomType == null) {
                logger.debug("Expecting an object but found null!");
            }
        }
        return atomTypes;
    }
731133
@Override
    public boolean matches(IAtom atom) {
        if (!atom.getSymbol().equals("H")) {
            return false;
        }

        if (atom.getFormalCharge() == 1) { // proton matches
            return true;
        }

        // hydrogens connected to other hydrogens, e.g., molecular hydrogen
        List<IAtom> list = invariants(atom).target().getConnectedAtomsList(atom);
        for (IAtom connAtom : list) {
            if (connAtom.getSymbol().equals("H")) {
                return true;
            }
        }

        // hydrogens connected to other than one other atom, e.g., bridging hydrogens
        if (invariants(atom).degree() > 1) {
            return true;
        }

        //isotopic hydrogen specifications, e.g. deuterium [2H] or tritium etc
        if (atom.getMassNumber() != null) {
            if (getMassNumber().intValue() == atom.getMassNumber().intValue()) return true;
        } else {
            // target atom is [H], so make sure query atom has mass number = 1
            if (getMassNumber() == 1) return true;
        }

        return false;
    }
1243159
public static Descriptor getDescriptor(Class<?> cls) throws IOException {

        String idl = ProtobufIDLGenerator.getIDL(cls);
        ProtoFile file = ProtoSchemaParser.parse(ProtobufIDLProxy.DEFAULT_FILE_NAME, idl);

        FileDescriptorProtoPOJO fileDescriptorProto = new FileDescriptorProtoPOJO();

        fileDescriptorProto.name = ProtobufIDLProxy.DEFAULT_FILE_NAME;
        fileDescriptorProto.pkg = file.getPackageName();
        fileDescriptorProto.dependencies = file.getDependencies();
        fileDescriptorProto.publicDependency = convertList(file.getPublicDependencies());
        fileDescriptorProto.weakDependency = null; // XXX

        fileDescriptorProto.messageTypes = new ArrayList<DescriptorProtoPOJO>();
        fileDescriptorProto.enumTypes = new ArrayList<EnumDescriptorProtoPOJO>();
        fileDescriptorProto.services = new ArrayList<ServiceDescriptorProtoPOJO>();

        Set<String> messageSet = new HashSet<String>();
        Set<String> enumSet = new HashSet<String>();

        List<com.squareup.protoparser.Type> typeElements = file.getTypes();
        if (typeElements != null) {

            for (com.squareup.protoparser.Type typeElement : typeElements) {
                if (typeElement instanceof MessageType) {
                    messageSet.add(typeElement.getName());
                } else if (typeElement instanceof EnumType) {
                    enumSet.add(typeElement.getName());
                }

            }

            for (com.squareup.protoparser.Type typeElement : typeElements) {

                if (typeElement instanceof MessageType) {
                    fileDescriptorProto.messageTypes.add(
                            getDescritorProtoPOJO(fileDescriptorProto, (MessageType) typeElement, messageSet, enumSet));
                } else if (typeElement instanceof EnumType) {
                    fileDescriptorProto.enumTypes.add(
                            getDescritorProtoPOJO(fileDescriptorProto, (EnumType) typeElement, messageSet, enumSet));
                }

            }
        }

        FileDescriptorProto fileproto;
        try {
            Codec<FileDescriptorProtoPOJO> descriptorCodec = ProtobufProxy.create(FileDescriptorProtoPOJO.class,
                    ProtobufProxy.isCacheEnabled(), ProtobufProxy.OUTPUT_PATH.get());
            byte[] bs = descriptorCodec.encode(fileDescriptorProto);
            fileproto = FileDescriptorProto.parseFrom(bs);
        } catch (InvalidProtocolBufferException e) {
            throw new IOException("Failed to parse protocol buffer descriptor for generated code.", e);
        }

        FileDescriptor fileDescriptor;
        try {
            fileDescriptor =
                    FileDescriptor.buildFrom(fileproto, new com.google.protobuf.Descriptors.FileDescriptor[] {});
        } catch (DescriptorValidationException e) {
            throw new IOException(e.getMessage(), e);
        }

        return fileDescriptor.getMessageTypes().get(0);
    }
652978
public static Map<Object, Object> getSupportedProperties(Object ref) {

		if (null == supportedMIMETypes) {
			synchronized (MIMETypesSupport.class) {
				if (null == supportedMIMETypes) {
					// Load the supported MIME types out of a properties file
					try (InputStream is = ClassLoaderResourceUtils.getResourceAsStream(MIME_PROPS_LOCATION, ref)) {
						supportedMIMETypes = new Properties();
						supportedMIMETypes.load(is);
					} catch (FileNotFoundException e) {
						throw new BundlingProcessException(
								"Error retrieving " + MIME_PROPS_LOCATION + ". Please check your classloader settings");
					} catch (IOException e) {
						throw new BundlingProcessException(
								"Error retrieving " + MIME_PROPS_LOCATION + ". Please check your classloader settings");
					}
				}
			}
		}

		return supportedMIMETypes;
	}
280223
public static List<Atom[]> getRotatedAtoms(MultipleAlignment multAln)
			throws StructureException {

		int size = multAln.size();

		List<Atom[]> atomArrays = multAln.getAtomArrays();
		for (int i = 0; i < size; i++) {
			if (atomArrays.get(i).length < 1)
				throw new StructureException(
						"Length of atoms arrays is too short! Size: "
								+ atomArrays.get(i).length);
		}

		List<Atom[]> rotatedAtoms = new ArrayList<Atom[]>();

		// TODO implement independent BlockSet superposition of the structure
		List<Matrix4d> transf = multAln.getBlockSet(0).getTransformations();

		if (transf == null) {

			logger.error("Alignment Transformations are not calculated. "
					+ "Superimposing to first structure as reference.");

			multAln = multAln.clone();
			MultipleSuperimposer imposer = new ReferenceSuperimposer();
			imposer.superimpose(multAln);
			transf = multAln.getBlockSet(0).getTransformations();
			assert (transf != null);
		}

		// Rotate the atom coordinates of all the structures
		for (int i = 0; i < size; i++) {
			// TODO handle BlockSet-level transformations
			// make sure this method has the same behavior as the other display.
			// -SB 2015-06

			// Assume all atoms are from the same structure
			Structure displayS = atomArrays.get(i)[0].getGroup().getChain()
					.getStructure().clone();

			// Get all the atoms and include ligands and hetatoms
			Atom[] rotCA = StructureTools.getRepresentativeAtomArray(displayS);
			List<Group> hetatms = StructureTools.getUnalignedGroups(rotCA);
			int index = rotCA.length;
			rotCA = Arrays.copyOf(rotCA, rotCA.length + hetatms.size());
			for (Group g : hetatms) {
				rotCA[index] = g.getAtom(0);
				index++;
			}

			// Transform the structure to ensure a full rotation in the display
			Calc.transform(displayS, transf.get(i));
			rotatedAtoms.add(rotCA);
		}

		return rotatedAtoms;
	}
437420
@Override
    public String getTypeDefinition(String typeName) throws AtlasException {
        final IDataType dataType = typeSystem.getDataType(IDataType.class, typeName);
        return TypesSerialization.toJson(typeSystem, dataType.getName());
    }
1232455
def _add_1(self,  hydrogen_name,  heavy_atom,  bonds):
        
        
        residue = heavy_atom.parent
        ffld = self.ffld[self.selection[residue]]
        bnd_len = self.bondfield.length
        anchor = bonds[0]
                
        # If not linear
        if self.bondfield.nonlinear.has_key(ffld[(  residue.resname,  
                                                    heavy_atom.name)]['type']):
            # returns tuple of two atoms
            bonded = self._find_secondary_anchors(residue,  heavy_atom,  anchor)

            if bonded:
                # Phenolic hydrogens,  etc.
                if self.bondfield.planer.has_key(ffld[( residue.resname,  
                                                        anchor.name)]['type']):
                    secondary_anchor = bonded[0]
                   
                    p0 = heavy_atom.coord - anchor.coord
                    d2 = secondary_anchor.coord - anchor.coord
                    p1 = normalize(cross_product(d2,  p0))
                    p2 = normalize(cross_product(p0,  p1))                     
                    vector = scale(p2,  TRI_TAN)
                    vector = normalize(add(p0,  vector))
                    
                    hydrogen_coord = add(heavy_atom.coord, 
                                        scale(vector,  
                                              bnd_len[(ffld[(residue.resname, 
                                                             heavy_atom.name)]['type'], 
                                              ffld[(residue.resname,  
                                                    hydrogen_name)]['type'])]))
                
                else: # Ser,  Cys,  Thr hydroxyl hydrogens
                    secondary_anchor = bonded[0]
                    vector = anchor.coord - secondary_anchor.coord
                    hydrogen_coord = add(heavy_atom.coord, 
                                        scale(vector,  
                                              bnd_len[(ffld[(residue.resname,  heavy_atom.name)]['type'],  
                                              ffld[(residue.resname,  hydrogen_name)]['type'])]    ))
                    
            elif len(bonds):
                d2 = [1.0, 0, 0]
                p0 = heavy_atom.coord - anchor.coord
                p1 = normalize(cross_product(d2,  p0))
                vector = scale(p1,  TET_TAN)
                vector = normalize(add(p0,  vector))
                
                hydrogen_coord = add(heavy_atom.coord, 
                                     scale(  vector,  
                                             bnd_len[(ffld[(residue.resname,  heavy_atom.name)]['type'],  
                                             ffld[(residue.resname,  hydrogen_name)]['type'])]    ))
            else:
                hydrogen_coord = random_sphere(heavy_atom.coord, 
                                               bnd_len[ (ffld[(residue.resname,  heavy_atom.name)]['type'], 
                                                         ffld[(residue.resname,  hydrogen_name)]['type']) ])

        elif len(bonds): # linear sum...amide,  tbu,  etc
            vector = [0.0, 0.0, 0.0]
            if heavy_atom.name == 'N': # Fix to get previous atom O from peptide bond. Ugly.
                prev_res = list(residue.get_id())
                prev_res[1] -= 1
                prev_res = tuple(prev_res)
                if residue.parent.child_dict.has_key(prev_res):
                    prev_res = residue.parent.child_dict[prev_res]
                    bonds.append(prev_res.child_dict['O'])
            for b in bonds:
                d = heavy_atom.coord - b.coord
                vector = add(vector,  d)
            vector = normalize(vector)
            hydrogen_coord = add(heavy_atom.coord, 
                                 scale(vector, 
                                 bnd_len[(ffld[(residue.resname,  heavy_atom.name)]['type'], 
                                          ffld[(residue.resname,  hydrogen_name)]['type']) ]))
        else:
            hydrogen_coord = random_sphere(heavy_atom.coord, 
                                           bnd_len[ (ffld[(residue.resname,  heavy_atom.name)]['type'], 
                                                     ffld[(residue.resname,  hydrogen_name)]['type']) ])
        
        return hydrogen_coord
672858
private boolean getPresenceOfHydroxy(IAtomContainer ac, IAtom atom) {
        IAtom neighbour0 = (IAtom) ac.getConnectedAtomsList(atom).get(0);
        List first = null;
        if (neighbour0.getSymbol().equals("C")) {
            first = ac.getConnectedAtomsList(neighbour0);
            for (int i = 0; i < first.size(); i++) {
                IAtom conAtom = (IAtom) first.get(i);
                if (conAtom.getSymbol().equals("O")) {
                    if (ac.getBond(neighbour0, conAtom).getOrder() == IBond.Order.SINGLE) {
                        if (ac.getConnectedBondsCount(conAtom) > 1 && getHydrogenCount(ac, conAtom) == 0) {
                            return false;
                        } else {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
821827
@Override
    public DescriptorValue calculate(IAtomContainer container) {

        double bpol = 0;
        int atomicNumber0;
        int atomicNumber1;
        double difference;
        try {
            IsotopeFactory ifac = Isotopes.getInstance();
            IElement element0;
            IElement element1;

            String symbol0;
            String symbol1;
            for (IBond bond : container.bonds()) {
                IAtom atom0 = bond.getBegin();
                IAtom atom1 = bond.getEnd();

                symbol0 = atom0.getSymbol();
                symbol1 = atom1.getSymbol();
                element0 = ifac.getElement(symbol0);
                element1 = ifac.getElement(symbol1);
                atomicNumber0 = element0.getAtomicNumber();
                atomicNumber1 = element1.getAtomicNumber();
                difference = polarizabilities[atomicNumber0] - polarizabilities[atomicNumber1];
                bpol += Math.abs(difference);
            }

            // after going through the bonds, we go through the atoms and see if they have
            // implicit H's and if so, consider the associated "implicit" bonds. Note that
            // if the count is UNSET, we assume it is 0
            for (IAtom atom : container.atoms()) {
                int impH = atom.getImplicitHydrogenCount() == CDKConstants.UNSET ? 0 : atom.getImplicitHydrogenCount();
                IElement elem = ifac.getElement(atom.getSymbol());
                int atnum = elem.getAtomicNumber();
                difference = Math.abs(polarizabilities[atnum] - polarizabilities[1]) * impH;
                bpol += difference;
            }
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(),
                    new DoubleResult(bpol), getDescriptorNames());
        } catch (Exception ex1) {
            logger.debug(ex1);
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(
                    Double.NaN), getDescriptorNames(), new CDKException("Problems with IsotopeFactory due to "
                    + ex1.toString(), ex1));
        }
    }
1140738
private boolean containsHpiJpi(Collection<String> bundledPlugins, String name) {
        return bundledPlugins.contains(name.replaceAll("\\.hpi",".jpi"))
                || bundledPlugins.contains(name.replaceAll("\\.jpi",".hpi"));
    }
639116
List<IStereoElement> recognise(Set<Projection> projections) {
        
        if (!projections.contains(Projection.Fischer))
            return Collections.emptyList();

        // build atom index and only recognize 2D depictions
        Map<IAtom,Integer> atomToIndex = new HashMap<IAtom, Integer>();
        for (IAtom atom : container.atoms()) {
            if (atom.getPoint2d() == null)
                return Collections.emptyList();
            atomToIndex.put(atom, atomToIndex.size());
        }
        
        RingSearch ringSearch = new RingSearch(container, graph);
        
        final List<IStereoElement> elements = new ArrayList<IStereoElement>(5);

        for (int v = 0; v < container.getAtomCount(); v++) {

            IAtom    focus = container.getAtom(v);
            Elements elem  = Elements.ofNumber(focus.getAtomicNumber());

            if (elem != Carbon)
                continue;
            if (ringSearch.cyclic(v))
                continue;
            if (stereocenters.elementType(v) != Tetracoordinate)
                continue;
            if (!stereocenters.isStereocenter(v))
                continue;

            ITetrahedralChirality element = newTetrahedralCenter(focus,
                                                                 neighbors(v, graph, bonds));

            if (element == null)
                continue;

            // east/west bonds must be to terminal atoms
            IAtom east = element.getLigands()[EAST];
            IAtom west = element.getLigands()[WEST];
            
            if (!east.equals(focus) && !isTerminal(east, atomToIndex))
                continue;
            if (!west.equals(focus) && !isTerminal(west, atomToIndex))
                continue;
            
            elements.add(element);
        }

        return elements;
    }
918547
public static ParticleSystem loadConfiguredSystem(InputStream ref)
			throws IOException {
      return loadConfiguredSystem(ref, null, null, null);
	}
19471
private IAtomContainer connectAtoms(String inputInchi, IAtomContainer inputMolecule,
            Map<Integer, IAtom> inchiAtomsByPosition) throws CDKException {
        String inchi = inputInchi;
        inchi = inchi.substring(inchi.indexOf('/') + 1);
        inchi = inchi.substring(inchi.indexOf('/') + 1);
        String connections = inchi.substring(1, inchi.indexOf('/'));
        Pattern connectionPattern = Pattern.compile("(-|\\(|\\)|,|([0-9])*)");
        Matcher match = connectionPattern.matcher(connections);
        Stack<IAtom> atomStack = new Stack<IAtom>();
        IAtomContainer inchiMolGraph = inputMolecule.getBuilder().newInstance(IAtomContainer.class);
        boolean pop = false;
        boolean push = true;
        while (match.find()) {
            String group = match.group();
            push = true;
            if (!group.isEmpty()) {
                if (group.matches("[0-9]*")) {
                    IAtom atom = inchiAtomsByPosition.get(Integer.valueOf(group));
                    if (!inchiMolGraph.contains(atom)) inchiMolGraph.addAtom(atom);
                    IAtom prevAtom = null;
                    if (atomStack.size() != 0) {
                        if (pop) {
                            prevAtom = atomStack.pop();
                        } else {
                            prevAtom = atomStack.get(atomStack.size() - 1);
                        }
                        IBond bond = inputMolecule.getBuilder().newInstance(IBond.class, prevAtom, atom,
                                IBond.Order.SINGLE);
                        inchiMolGraph.addBond(bond);
                    }
                    if (push) {
                        atomStack.push(atom);
                    }
                } else if (group.equals("-")) {
                    pop = true;
                    push = true;
                } else if (group.equals(",")) {
                    atomStack.pop();
                    pop = false;
                    push = false;
                } else if (group.equals("(")) {
                    pop = false;
                    push = true;
                } else if (group.equals(")")) {
                    atomStack.pop();
                    pop = true;
                    push = true;
                } else {
                    throw new CDKException("Unexpected token " + group + " in connection table encountered.");
                }
            }
        }
        //put any unconnected atoms in the output as well
        for (IAtom at : inchiAtomsByPosition.values()) {
            if (!inchiMolGraph.contains(at)) inchiMolGraph.addAtom(at);
        }
        return inchiMolGraph;
    }
950392
public static List<MethodDefinition> getMethodDefinitions(String sDefPID)
            throws IOException {
        return MethodDefinition.parse(Administrator.DOWNLOADER
                .getDatastreamDissemination(sDefPID, "METHODMAP", null));
    }