Task: Fixes #4582 (rdkit/rdkit#4587)

org: rdkit
repo: rdkit
pr_number: 4587
issue_title: Fixes #4582
issue_body: The changes in #4190 introduced a problem in the SMILES for double bond stereo around ring closures in some rare cases (~60 molecules in ChEMBL27). This fixes that problem.

This isn't the most satisfying fix since there are definitely still some errors that can be found when using random SMILES output order, but I'm not sure how long it's going to take to fix the full problem, so I'm suggesting we merge this under the theory that a partial fix is better than nothing.

As an aside: the code in `Canon.cpp::canonicalizeDoubleBond()` really ought to be refactored and cleaned up.
resolved_issues: number: 4582
title: Incorrect double bond stereo in output SMILES around ring closures
body: **Describe the bug**

Code to reproduce this:
```
from rdkit import Chem
m = Chem.MolFromMolBlock('''CHEMBL409450
     RDKit          2D

 22 25  0  0  0  0  0  0  0  0999 V2000
   -1.1669    1.3591    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.6820    0.6916    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.9516    1.1041    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.9516    0.2791    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0
   -2.5647    1.6562    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -2.3931    2.4631    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.6085    2.7181    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.9954    2.1661    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.1669    0.0242    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.9120   -0.7604    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.3969   -1.4279    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.9120   -2.0953    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0
   -0.1274   -1.8404    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.1274   -1.0154    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.5871   -2.2529    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    1.3016   -1.8404    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    1.3016   -1.0154    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.5871   -0.6029    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -2.2219   -1.4279    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
    0.1430    0.6916    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0
    0.5555    1.4061    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
    2.0160   -2.2529    0.0000 Br  0  0  0  0  0  0  0  0  0  0  0  0
  1  2  1  0
  1  3  2  0
  1  8  1  0
  9  2  1  0
  2 20  2  0
  3  4  1  0
  3  5  1  0
  9  4  1  0
  5  6  2  0
  6  7  1  0
  8  7  2  0
  9 10  2  0
 10 11  1  0
 10 14  1  0
 11 12  1  0
 11 19  2  0
 13 12  1  0
 13 14  2  0
 13 15  1  0
 14 18  1  0
 15 16  2  0
 16 17  1  0
 22 16  1  0
 17 18  2  0
 20 21  1  0
M  END''')
print(Chem.MolToSmiles(m))
```

The output is `O=C1Nc2cc(Br)ccc2/C1=C1/Nc2ccccc2/C1=N/O`, but it should be  `O=C1Nc2cc(Br)ccc2/C1=C1/Nc2ccccc2/C1=N\O`

This was introduced as part of #4190 

**Configuration (please complete the following information):**
 - RDKit version: >=2021.03.3
 - OS: all


Reference solution:
fix_patch: diff --git a/.azure-pipelines/linux_build_cartridge.yml b/.azure-pipelines/linux_build_cartridge.yml
index 500cd038a17..e0a54564db5 100644
--- a/.azure-pipelines/linux_build_cartridge.yml
+++ b/.azure-pipelines/linux_build_cartridge.yml
@@ -1,10 +1,12 @@
 steps:
 - bash: |
     sudo apt-get update
-    sudo apt-get remove postgresql postgresql-13 postgresql-client-13 postgresql-common postgresql-client-common
-    sudo apt purge postgresql postgresql-13 postgresql-client-13 postgresql-common postgresql-client-common
+    sudo apt-get remove postgresql-14 postgresql-client-14
+    sudo apt-get remove postgresql postgresql-common postgresql-client-common
+    sudo apt purge postgresql-14 postgresql-client-14
+    sudo apt purge postgresql postgresql-common postgresql-client-common
     sudo apt-get install -y libboost-all-dev postgresql-common postgresql-12 postgresql-server-dev-12
-    echo "add user"
+    echo "add postgres user"
     sudo -u postgres createuser -s `whoami`
   displayName: Setup build environment
 - bash: |
diff --git a/Code/GraphMol/Canon.cpp b/Code/GraphMol/Canon.cpp
index faa822a07df..ebd50d68781 100644
--- a/Code/GraphMol/Canon.cpp
+++ b/Code/GraphMol/Canon.cpp
@@ -1,5 +1,5 @@
 //
-//  Copyright (C) 2001-2020 Greg Landrum and Rational Discovery LLC
+//  Copyright (C) 2001-2021 Greg Landrum and other RDKit contributors
 //
 //   @@ All Rights Reserved @@
 //  This file is part of the RDKit.
@@ -136,6 +136,17 @@ void switchBondDir(Bond *bond) {
   }
 }
 
+namespace {
+bool isClosingRingBond(Bond *bond) {
+  if (bond == nullptr) {
+    return false;
+  }
+  auto beginIdx = bond->getBeginAtomIdx();
+  auto endIdx = bond->getEndAtomIdx();
+  return beginIdx > endIdx && beginIdx - endIdx > 1 &&
+         bond->hasProp(common_properties::_TraversalRingClosureBond);
+}
+}  // namespace
 // FIX: this may only be of interest from the SmilesWriter, should we
 // move it there?
 //
@@ -354,27 +365,17 @@ void canonicalizeDoubleBond(Bond *dblBond, UINT_VECT &bondVisitOrders,
     // stereochemistry, we need to flip the setting on the other bond:
     const INT_VECT &stereoAtoms = dblBond->getStereoAtoms();
 
-    auto isClosingRingBond = [](Bond *bond) {
-      if (bond == nullptr) {
-        return false;
-      }
-      auto beginIdx = bond->getBeginAtomIdx();
-      auto endIdx = bond->getEndAtomIdx();
-      return beginIdx > endIdx && beginIdx - endIdx > 1 &&
-             bond->hasProp(common_properties::_TraversalRingClosureBond);
-    };
-
     auto isFlipped = false;
 
-    if (atom1->getDegree() == 3 &&
+    if (atom1->getDegree() == 3 &&  // atom1ControllingBond == firstFromAtom1 &&
         std::find(stereoAtoms.begin(), stereoAtoms.end(),
                   static_cast<int>(atom1ControllingBond->getOtherAtomIdx(
                       atom1->getIdx()))) == stereoAtoms.end()) {
       isFlipped = true;
       atom2Dir = flipBondDir(atom2Dir);
     }
-    // std::cerr<<" 0 set bond 2: "<<firstFromAtom2->getIdx()<<"
-    // "<<atom2Dir<<std::endl;
+    // std::cerr << " 0 set bond 2: " << firstFromAtom2->getIdx() << " "
+    //           << atom2Dir << std::endl;
     if (atom2->getDegree() == 3 &&
         std::find(stereoAtoms.begin(), stereoAtoms.end(),
                   static_cast<int>(firstFromAtom2->getOtherAtomIdx(
@@ -383,14 +384,12 @@ void canonicalizeDoubleBond(Bond *dblBond, UINT_VECT &bondVisitOrders,
       atom2Dir = flipBondDir(atom2Dir);
     }
 
-    if (!isFlipped && (isClosingRingBond(dblBond) ||
-                       (isClosingRingBond(secondFromAtom1) &&
-                        !secondFromAtom1->getIsAromatic() &&
-                        secondFromAtom1->getBondDir() != Bond::NONE))) {
+    if (!isFlipped && isClosingRingBond(dblBond)) {
       atom2Dir = flipBondDir(atom2Dir);
     }
-    // std::cerr<<" 1 set bond 2: "<<firstFromAtom2->getIdx()<<"
-    // "<<atom2Dir<<std::endl;
+
+    // std::cerr << " 1 set bond 2: " << firstFromAtom2->getIdx() << " "
+    //           << atom2Dir << std::endl;
     firstFromAtom2->setBondDir(atom2Dir);
 
     bondDirCounts[firstFromAtom2->getIdx()] += 1;
@@ -554,7 +553,11 @@ void canonicalizeDoubleBond(Bond *dblBond, UINT_VECT &bondVisitOrders,
     if (dblBondPresent && otherAtom3Bond &&
         otherAtom3Bond->getBondDir() == Bond::NONE) {
       // std::cerr<<"set!"<<std::endl;
-      otherAtom3Bond->setBondDir(firstFromAtom2->getBondDir());
+      auto dir = firstFromAtom2->getBondDir();
+      if (isClosingRingBond(otherAtom3Bond)) {
+        dir = flipBondDir(dir);
+      }
+      otherAtom3Bond->setBondDir(dir);
       bondDirCounts[otherAtom3Bond->getIdx()] += 1;
       atomDirCounts[atom3->getIdx()] += 1;
     }