chem.MolfileSaver.prototype.writeCTab2000 = function()

in gsoc2022/seagrid-rich-client/molview/src/js/chem/chem/molfile.js [1360:1641]


chem.MolfileSaver.prototype.writeCTab2000 = function (rgroups)
{
	this.writeCTab2000Header();

	this.mapping = {};
	var i = 1;

	var atomList_list = [];
	var atomLabel_list = [];
	this.molecule.atoms.each(function (id, atom)
	{
		this.writePaddedFloat(atom.pp.x, 10, 4);
		this.writePaddedFloat(-atom.pp.y, 10, 4);
		this.writePaddedFloat(0, 10, 4);
		this.writeWhiteSpace();

		var label = atom.label;
		if(atom.atomList != null)
		{
			label = 'L';
			atomList_list.push(id);
		}
		else if(chem.Element.getElementByLabel(label) == null && ['A', 'Q', 'X', '*', 'R#'].indexOf(label) == -1)
		{
			label = 'C';
			atomLabel_list.push(id);
		}
		this.writePadded(label, 3);
		this.writePaddedNumber(0, 2);
		this.writePaddedNumber(0, 3);
		this.writePaddedNumber(0, 3);

		if(isUndefined(atom.hCount))
			atom.hCount = 0;
		this.writePaddedNumber(atom.hCount, 3);

		if(isUndefined(atom.stereoCare))
			atom.stereoCare = 0;
		this.writePaddedNumber(atom.stereoCare, 3);

		this.writePaddedNumber(atom.explicitValence < 0 ? 0 : (atom.explicitValence == 0 ? 15 : atom.explicitValence), 3);

		this.writePaddedNumber(0, 3);
		this.writePaddedNumber(0, 3);
		this.writePaddedNumber(0, 3);

		if(isUndefined(atom.aam))
			atom.aam = 0;
		this.writePaddedNumber(atom.aam, 3);

		if(isUndefined(atom.invRet))
			atom.invRet = 0;
		this.writePaddedNumber(atom.invRet, 3);

		if(isUndefined(atom.exactChangeFlag))
			atom.exactChangeFlag = 0;
		this.writePaddedNumber(atom.exactChangeFlag, 3);

		this.writeCR();

		this.mapping[id] = i;
		i++;
	}, this);

	this.bondMapping = {};
	i = 1;
	this.molecule.bonds.each(function (id, bond)
	{
		this.bondMapping[id] = i++;
		this.writePaddedNumber(this.mapping[bond.begin], 3);
		this.writePaddedNumber(this.mapping[bond.end], 3);
		this.writePaddedNumber(bond.type, 3);

		if(isUndefined(bond.stereo))
			bond.stereo = 0;
		this.writePaddedNumber(bond.stereo, 3);

		this.writeWhiteSpace(3);

		if(isUndefined(bond.topology))
			bond.topology = 0;
		this.writePaddedNumber(bond.topology, 3);

		if(isUndefined(bond.reactingCenterStatus))
			bond.reactingCenterStatus = 0;
		this.writePaddedNumber(bond.reactingCenterStatus, 3);

		this.writeCR();
	}, this);

	while(atomLabel_list.length > 0)
	{
		this.write('A  ');
		this.writePaddedNumber(atomLabel_list[0] + 1, 3);
		this.writeCR();
		this.writeCR(this.molecule.atoms.get(atomLabel_list[0]).label);
		atomLabel_list.splice(0, 1);
	}

	var charge_list = new Array();
	var isotope_list = new Array();
	var radical_list = new Array();
	var rglabel_list = new Array();
	var rglogic_list = new Array();
	var aplabel_list = new Array();
	var rbcount_list = new Array();
	var unsaturated_list = new Array();
	var substcount_list = new Array();

	this.molecule.atoms.each(function (id, atom)
	{
		if(atom.charge != 0)
			charge_list.push([id, atom.charge]);
		if(atom.isotope != 0)
			isotope_list.push([id, atom.isotope]);
		if(atom.radical != 0)
			radical_list.push([id, atom.radical]);
		if(atom.rglabel != null && atom.label == 'R#')
		{ // TODO need to force rglabel=null when label is not 'R#'
			for(var rgi = 0; rgi < 32; rgi++)
			{
				if(atom.rglabel & (1 << rgi)) rglabel_list.push([id, rgi + 1]);
			}
		}
		if(atom.attpnt != null)
			aplabel_list.push([id, atom.attpnt]);
		if(atom.ringBondCount != 0)
			rbcount_list.push([id, atom.ringBondCount]);
		if(atom.substitutionCount != 0)
			substcount_list.push([id, atom.substitutionCount]);
		if(atom.unsaturatedAtom != 0)
			unsaturated_list.push([id, atom.unsaturatedAtom]);
	});

	if(rgroups)
		rgroups.each(function (rgid, rg)
		{
			if(rg.resth || rg.ifthen > 0 || rg.range.length > 0)
			{
				var line = '  1 ' + util.paddedInt(rgid, 3) + ' ' + util.paddedInt(rg.ifthen, 3) + ' ' + util.paddedInt(rg.resth ? 1 : 0, 3) + '   ' + rg.range;
				rglogic_list.push(line);
			}
		});

	var writeAtomPropList = function (prop_id, values)
	{
		while(values.length > 0)
		{
			var part = new Array();

			while(values.length > 0 && part.length < 8)
			{
				part.push(values[0]);
				values.splice(0, 1);
			}

			this.write(prop_id);
			this.writePaddedNumber(part.length, 3);

			util.each(part, function (value)
			{
				this.writeWhiteSpace();
				this.writePaddedNumber(this.mapping[value[0]], 3);
				this.writeWhiteSpace();
				this.writePaddedNumber(value[1], 3);
			}, this);

			this.writeCR();
		}
	};

	writeAtomPropList.call(this, 'M  CHG', charge_list);
	writeAtomPropList.call(this, 'M  ISO', isotope_list);
	writeAtomPropList.call(this, 'M  RAD', radical_list);
	writeAtomPropList.call(this, 'M  RGP', rglabel_list);
	for(var j = 0; j < rglogic_list.length; ++j)
	{
		this.write('M  LOG' + rglogic_list[j] + '\n');
	}
	writeAtomPropList.call(this, 'M  APO', aplabel_list);
	writeAtomPropList.call(this, 'M  RBC', rbcount_list);
	writeAtomPropList.call(this, 'M  SUB', substcount_list);
	writeAtomPropList.call(this, 'M  UNS', unsaturated_list);

	if(atomList_list.length > 0)
	{
		for(j = 0; j < atomList_list.length; ++j)
		{
			var aid = atomList_list[j];
			var atomList = this.molecule.atoms.get(aid).atomList;
			this.write('M  ALS');
			this.writePaddedNumber(aid + 1, 4);
			this.writePaddedNumber(atomList.ids.length, 3);
			this.writeWhiteSpace();
			this.write(atomList.notList ? 'T' : 'F');

			var labelList = atomList.labelList();
			for(var k = 0; k < labelList.length; ++k)
			{
				this.writeWhiteSpace();
				this.writePadded(labelList[k], 3);
			}
			this.writeCR();
		}
	}

	var sgmap = {},
		cnt = 1,
		sgmapback = {};
	var sgorder = this.molecule.sGroupForest.getSGroupsBFS();
	util.each(sgorder, function (id)
	{
		sgmapback[cnt] = id;
		sgmap[id] = cnt++;
	}, this);
	for(var q = 1; q < cnt; ++q)
	{ // each group on its own
		var id = sgmapback[q];
		var sgroup = this.molecule.sgroups.get(id);
		this.write('M  STY');
		this.writePaddedNumber(1, 3);
		this.writeWhiteSpace(1);
		this.writePaddedNumber(q, 3);
		this.writeWhiteSpace(1);
		this.writePadded(sgroup.type, 3);
		this.writeCR();

		// TODO: write subtype, M SST

		this.write('M  SLB');
		this.writePaddedNumber(1, 3);
		this.writeWhiteSpace(1);
		this.writePaddedNumber(q, 3);
		this.writeWhiteSpace(1);
		this.writePaddedNumber(q, 3);
		this.writeCR();

		var parentid = this.molecule.sGroupForest.parent.get(id);
		if(parentid >= 0)
		{
			this.write('M  SPL');
			this.writePaddedNumber(1, 3);
			this.writeWhiteSpace(1);
			this.writePaddedNumber(q, 3);
			this.writeWhiteSpace(1);
			this.writePaddedNumber(sgmap[parentid], 3);
			this.writeCR();
		}

		// connectivity
		if(sgroup.type == 'SRU' && sgroup.data.connectivity)
		{
			var connectivity = '';
			connectivity += ' ';
			connectivity += util.stringPadded(q.toString(), 3);
			connectivity += ' ';
			connectivity += util.stringPadded(sgroup.data.connectivity, 3, true);
			this.write('M  SCN');
			this.writePaddedNumber(1, 3);
			this.write(connectivity.toUpperCase());
			this.writeCR();
		}

		if(sgroup.type == 'SRU')
		{
			this.write('M  SMT ');
			this.writePaddedNumber(q, 3);
			this.writeWhiteSpace();
			this.write(sgroup.data.subscript || 'n');
			this.writeCR();
		}

		this.writeCR(sgroup.saveToMolfile(this.molecule, sgmap, this.mapping, this.bondMapping));
	}

	// TODO: write M  APO
	// TODO: write M  AAL
	// TODO: write M  RGP
	// TODO: write M  LOG

	this.writeCR('M  END');
};