Task: Sanitize number of radical electrons in case of invalid value assigned by CXSMILES (rdkit/rdkit#6842)

org: rdkit
repo: rdkit
pr_number: 6842
issue_title: Sanitize number of radical electrons in case of invalid value assigned by CXSMILES
issue_body: #### Reference Issue
Fixes #6370 

#### What does this implement/fix? Explain your changes.
Number of radical electrons are first assigned by the regular SMILES, and then get overridden by the CXSMILES extension. For example,

```python
Chem.MolFromSmiles('[CH4]').Debug()
#	0 6 C chg: 0  deg: 0 exp: 4 imp: 0 hyb: 4 arom?: 0 chi: 0
Chem.MolFromSmiles('[CH4] |^1:0|').Debug()
#	0 6 C chg: 0  deg: 0 exp: 4 imp: 0 hyb: 4 arom?: 0 chi: 0 rad: 1
Chem.MolFromSmiles('[CH4] |^2:0|').Debug()
#	0 6 C chg: 0  deg: 0 exp: 4 imp: 0 hyb: 4 arom?: 0 chi: 0 rad: 2
```

The radical info from CXSMILES may be invalid and therefore should be sanitized. However, current implementation of `assignRadicals()` within `sanitizeMol()` will do nothing if the preset number of radical electrons is non-zero. The fix is then to allow such sanitization by removing the condition `if (atom->getNumRadicalElectrons())`.

Unittests are added for a set of CXSMILES:
1. `[XHn] |^m:0|` where X is the element symbol, n = 1, ..., valence, m = 1, ..., 7 denotes the radical type.
2. `[NH4+] |^m:0|` where m = 1, ..., 7 denotes the radical type.

I also fix a minor issue in `calcImplicitValence()` where `d_implicitValence` is not overwritten by the return value.
resolved_issues: number: 6370
title: non-physical radical counts being preserved
body: 
**Describe the bug**
Sanitization is leaving radicals on molecules where they don't make sense.

**To Reproduce**
```
In [8]: Chem.MolFromSmiles('[NH4+] |^1:0|').Debug()
Atoms:
	0 7 N chg: 1  deg: 0 exp: 4 imp: 0 hyb: 4 arom?: 0 chi: 0 rad: 1
Bonds:

In [9]: Chem.MolFromSmiles('[CH4] |^1:0|').Debug()
Atoms:
	0 6 C chg: 0  deg: 0 exp: 4 imp: 0 hyb: 4 arom?: 0 chi: 0 rad: 1
Bonds:

```
Neither of those should have a radical on it.

**Configuration (please complete the following information):**
 - RDKit version: all
 - OS: all


Reference solution:
fix_patch: diff --git a/Code/GraphMol/MolOps.cpp b/Code/GraphMol/MolOps.cpp
index 4ba259f3808..971ee8c7217 100644
--- a/Code/GraphMol/MolOps.cpp
+++ b/Code/GraphMol/MolOps.cpp
@@ -388,9 +388,8 @@ void adjustHs(RWMol &mol) {
 void assignRadicals(RWMol &mol) {
   for (auto atom : mol.atoms()) {
     // we only put automatically assign radicals to things that
-    // don't have them already and don't have implicit Hs:
-    if (!atom->getNoImplicit() || atom->getNumRadicalElectrons() ||
-        !atom->getAtomicNum()) {
+    // don't have implicit Hs:
+    if (!atom->getNoImplicit() || !atom->getAtomicNum()) {
       continue;
     }
     const auto &valens =
diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index f392dd3e07b..7f3fce596cf 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -10,7 +10,7 @@ GitHub)
 
 ## Backwards incompatible changes
 - Two changes to improve the defaults for conformer generation: the functions EmbedMolecule() and EmbedMultipleConfis() now use ETKDGv3 by default (previously they were using ETKDGV1) and only consider heavy atoms when calculating RMSD for conformer pruning (previously Hs were alos considered).
-
+- The way that the number of radical electrons is calculated for atoms coming from mol blocks has been changed. Systems like a `[CH]` marked as a `DOUBLET` will now have three radical electrons assigned. This is consistent with the value from SMILES.
 
 ## New Features and Enhancements: