diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b0fff8df3b3dc0d8ab6e6286e2af5931f2e6ccfd..a95f75e2f6d461204cdcb2a1b0e50cbb1c3afca1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -12,7 +12,7 @@ default:
   before_script:
     - mkdir -p images && mkdir -p doc/
     - git clone https://eicweb.phy.anl.gov/EIC/detectors/accelerator.git && ln -s accelerator/eic 
-    - git clone https://eicweb.phy.anl.gov/EIC/detectors/ip6.git && mkdir ip6_build && cd ip6_build && cmake ../ip6/. -DCMAKE_INSTALL_PREFIX=/usr/local && make -j20 && make install  && cd .. && ln -s ip6/ip6 
+    - git clone https://eicweb.phy.anl.gov/EIC/detectors/ip6.git  eic_ip6 && mkdir ip6_build && cd ip6_build && cmake ../eic_ip6/. -DCMAKE_INSTALL_PREFIX=/usr/local && make -j20 && make install  && cd .. && ln -s eic_ip6/ip6 
     - mkdir build && cd build && cmake ../. -DCMAKE_INSTALL_PREFIX=/usr/local && make -j20 && make install  && cd ..
   artifacts:
     paths:
diff --git a/compact/definitions.xml b/compact/definitions.xml
index 750a8ab3309436f4690929947c059bdca708dae9..c7321b9729a1c651422d86b0627449cf6cac8872 100644
--- a/compact/definitions.xml
+++ b/compact/definitions.xml
@@ -423,6 +423,7 @@
     </comment>
     <constant name="RICHZMin" value="SolenoidYokeEndcap_zmin + 1 * cm"/>
     <constant name="RICHRMin" value="15 * cm"/>
+    <constant name="RICHRMax" value="60 * cm"/>
     <constant name="RICHDepth" value="1 * m"/>
 
 
diff --git a/compact/display.xml b/compact/display.xml
index b2ad9891af9b6c0d03f7b08abd2cd7becf420054..ae6af1bf18fd1819d37492fc0e8484eee122e111 100644
--- a/compact/display.xml
+++ b/compact/display.xml
@@ -53,11 +53,11 @@
     <comment>
       Deprecated colors.
     </comment>
-    <vis name="GreenVis"       alpha="0.2"  r= "0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
+    <vis name="GreenVis"       alpha="1.0"  r= "0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
     <vis name="RedVis"         alpha="0.2"  r= "1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/>
     <vis name="RPVis"          alpha="0.99"  r= "1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/>
     <vis name="RPLayerVis"     alpha="0.99"  r= "0.0" g="0.7" b="0.3" showDaughters="true" visible="true" lineStyle="solid" drawingStyle="solid" />
-    <vis name="BlueVis"        alpha="0.2"  r= "0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
+    <vis name="BlueVis"        alpha="1.0"  r= "0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
     <vis name="OrangeVis"      alpha="1.0"  r= "1.0" g="0.45" b="0.0" showDaughters="true" visible="true"/>
     <vis name="RedGreenVis"    alpha="0.5"  r= "1.0" g="1.0" b="0.0" showDaughters="true" visible="true"/>
     <vis name="BlueGreenVis"   alpha="0.5"  r= "0.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
@@ -66,5 +66,5 @@
     <vis name="RBG015"         alpha="0.5"  r= "0.0" g=".2"  b="1.0" showDaughters="true" visible="true"/>
     <vis name="RBG510"         alpha="0.5"  r= "1.0" g=".2"  b="0.0" showDaughters="true" visible="true"/>
     <vis name="RBG"            alpha="0.5"  r= "1.0" g="1.0" b="1.0" showDaughters="true" visible="true"/>
-    <vis name="GrayVis"        alpha="0.5"  r= "0.75" g="0.75" b="0.75" showDaughters="true" visible="true"/>
+    <vis name="GrayVis"        alpha="1.0"  r= "0.75" g="0.75" b="0.75" showDaughters="true" visible="true"/>
   </display>
diff --git a/compact/forward_rich.xml b/compact/forward_rich.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d94e9e162592d826ae9e7f1f14216cf6f39fc94f
--- /dev/null
+++ b/compact/forward_rich.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd>
+  <define>
+  </define>
+
+  <detectors>
+    <detector id="ForwardRICH_ID" name="ForwardRICH" type="refdet_ForwardRICH" readout="ForwardRICHHits" vis="BlueVis">
+      <dimensions z0="RICHZMin" length="RICHDepth+20*cm" rmin="RICHRMin" rmax1="RICHRMax*cm" rmax2="RICHRMin+80*cm"/>
+      <radiator material="N2cherenkov" />
+      <mcppmt zdiff="15.0*cm" rmin="SolenoidYokeEndcapP_rmin - 10*cm" rmax="SolenoidYokeEndcapP_rmin + 80*cm" rtol="1.0*cm" vis="BlueVis"
+              module_size="10*cm" module_gap="0.2*cm" thickness="1.0*cm" material="Quartz" />
+      <tank zdiff="5.0*cm" length="RICHDepth" gas="N2cherenkov" vis="GreenVis"
+            rmin="RICHRMin" rmax1="RICHRMin+40*cm" rmax2="RICHRMin+80*cm" />
+      <mirror zdiff="RICHDepth+7.0*cm" thickness="1*mm" material="PyrexGlass" vis="GrayVis">
+        <slice focus="10*cm" curve="300*cm" rmin="RICHRMin" rmax="RICHRMin+80*cm" phiw="59*degree" rotz="0*degree" />
+        <slice focus="10*cm" curve="300*cm" rmin="RICHRMin" rmax="RICHRMin+80*cm" phiw="59*degree" rotz="60*degree" />
+        <slice focus="10*cm" curve="300*cm" rmin="RICHRMin" rmax="RICHRMin+80*cm" phiw="59*degree" rotz="120*degree" />
+        <slice focus="10*cm" curve="300*cm" rmin="RICHRMin" rmax="RICHRMin+80*cm" phiw="59*degree" rotz="180*degree" />
+        <slice focus="10*cm" curve="300*cm" rmin="RICHRMin" rmax="RICHRMin+80*cm" phiw="59*degree" rotz="240*degree" />
+        <slice focus="10*cm" curve="300*cm" rmin="RICHRMin" rmax="RICHRMin+80*cm" phiw="59*degree" rotz="300*degree" />
+      </mirror>
+    </detector>
+  </detectors>
+
+  <readouts>
+    <readout name="ForwardRICHHits">
+      <segmentation type="CartesianGridXY" grid_size_x="3*mm" grid_size_y="3*mm" />
+      <id>system:8,layer:4,piece:4,module:14,x:32:-16,y:-16</id>
+    </readout>
+  </readouts>
+
+</lccdd>
diff --git a/reference_detector.xml b/reference_detector.xml
index 2b2aa0a187a9972863582407d01c70a05726f43a..463faf881db2a2176313134253c3b407b009a4ca 100644
--- a/reference_detector.xml
+++ b/reference_detector.xml
@@ -117,8 +117,8 @@
   <include ref="compact/solenoid.xml"/>
   <include ref="compact/ecal.xml"/>
   <include ref="compact/hcal.xml"/>
+  <include ref="compact/forward_rich.xml"/>
   <!--
-  <include ref="compact/reference_detector_rich.xml"/>
   <include ref="compact/roman_pots.xml"/>
   -->
   <!--
diff --git a/scripts/view1/.DAWN_1.history b/scripts/view1/.DAWN_1.history
index 42729c65bc406cdb4b98cfef27a6e803548a0bba..3a43b62a9d1b3c8407d8d42151e4218e629c4f3c 100644
--- a/scripts/view1/.DAWN_1.history
+++ b/scripts/view1/.DAWN_1.history
@@ -5,10 +5,10 @@
 0
 0
 0
-16.4
+1
 1
 0.001
-0
+1
 1
 1
 1
diff --git a/scripts/view1/generate_eps b/scripts/view1/generate_eps
index 371e1d90ad31ae49101391d5a6f0e5c127e1193d..c863fbaddfb46cc5d1342d0ca9eb2766b31ac3dd 100755
--- a/scripts/view1/generate_eps
+++ b/scripts/view1/generate_eps
@@ -9,8 +9,8 @@ function print_the_help {
   exit 
 }
 
-FILE_TAG="view1"
-INPUT_FILE="g4_0000.prim"
+FILE_TAG="view01"
+INPUT_FILE="../../g4_0000.prim"
 
 
 POSITIONAL=()
@@ -44,6 +44,7 @@ done
 set -- "${POSITIONAL[@]}" # restore positional parameters
 
 
+# Side  view
 dawncut 1 0 0 1 ${INPUT_FILE} ${FILE_TAG}_temp0.prim 
 dawncut -1 0 0 1 ${FILE_TAG}_temp0.prim  ${FILE_TAG}.prim
 dawn -d ${FILE_TAG}.prim 
@@ -55,3 +56,15 @@ gs -o ${FILE_TAG}.pdf -sDEVICE=pdfwrite \
 pdftoppm ${FILE_TAG}.pdf ${FILE_TAG} -png -singlefile -cropbox
 
 
+# Top view
+dawncut 0 1 0 1 ${INPUT_FILE} ${FILE_TAG}_temp0.prim 
+dawncut 0 -1 0 1 ${FILE_TAG}_temp0.prim  ${FILE_TAG}.prim
+../../bin/dawn_tweak --theta 270
+dawn -d ${FILE_TAG}.prim 
+ps2pdf ${FILE_TAG}.eps ${FILE_TAG}_top_full.pdf
+gs -o ${FILE_TAG}_top.pdf -sDEVICE=pdfwrite \
+  -c "[/CropBox [51 250 550 590] /PAGES pdfmark" \
+  -f ${FILE_TAG}_top_full.pdf
+
+pdftoppm ${FILE_TAG}_top.pdf ${FILE_TAG}_top -png -singlefile -cropbox
+
diff --git a/src/ForwardRICH_geo.cpp b/src/ForwardRICH_geo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6520c30aac30492a8950c1590661bce57e089e47
--- /dev/null
+++ b/src/ForwardRICH_geo.cpp
@@ -0,0 +1,263 @@
+//==========================================================================
+//  Forward Ring Imaging Cherenkov Detector
+//--------------------------------------------------------------------------
+//
+// Author: C. Peng (ANL)
+// Date: 09/30/2020
+//
+//==========================================================================
+
+#include <XML/Helper.h>
+#include "TMath.h"
+#include "TString.h"
+#include "Math/Point2D.h"
+#include "DDRec/Surface.h"
+#include "DDRec/DetectorData.h"
+#include "DD4hep/OpticalSurfaces.h"
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/Printout.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::rec;
+
+typedef ROOT::Math::XYPoint Point;
+
+
+// check if a square in a ring
+inline bool in_ring(const Point &pt, double side, double rmin, double rmax, double phmin, double phmax)
+{
+    if (pt.r() > rmax || pt.r() < rmin) {
+        return false;
+    }
+
+    // check four corners
+    std::vector<Point> pts {
+        Point(pt.x() - side/2., pt.y() - side/2.),
+        Point(pt.x() - side/2., pt.y() + side/2.),
+        Point(pt.x() + side/2., pt.y() - side/2.),
+        Point(pt.x() + side/2., pt.y() + side/2.),
+    };
+    for (auto &p : pts) {
+        if (p.r() > rmax || p.r() < rmin || p.phi() > phmax || p.phi() < phmin) {
+            return false;
+        }
+    }
+    return true;
+}
+
+// check if a square is overlapped with the others
+inline bool overlap(const Point &pt, double side, const std::vector<Point> &pts)
+{
+    for (auto &p : pts) {
+        auto pn = (p - pt)/side;
+        if ((std::abs(pn.x()) < 1. - 1e-6) && (std::abs(pn.y()) < 1. - 1e-6)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+// a helper function to recursively fill square in a ring
+void add_square(Point p, std::vector<Point> &res, double lside, double rmin, double rmax,
+                double phmin, double phmax)
+{
+    // outside of the ring or overlapping
+    if (!in_ring(p, lside, rmin, rmax, phmin, phmax) || overlap(p, lside, res)) {
+        return;
+    }
+
+    res.emplace_back(p);
+
+    // check adjacent squares
+    add_square(Point(p.x() + lside, p.y()), res, lside, rmin, rmax, phmin, phmax);
+    add_square(Point(p.x() - lside, p.y()), res, lside, rmin, rmax, phmin, phmax);
+    add_square(Point(p.x(), p.y() + lside), res, lside, rmin, rmax, phmin, phmax);
+    add_square(Point(p.x(), p.y() - lside), res, lside, rmin, rmax, phmin, phmax);
+}
+
+// fill squares
+std::vector<Point> fill_squares(Point ref, double lside, double rmin, double rmax,
+                                double phmin = 0., double phmax = 2.*M_PI)
+{
+    // start with a seed square and find one in the ring
+    // move to center
+    ref = ref - Point(int(ref.x()/lside)*lside, int(ref.y()/lside)*lside);
+
+    auto find_seed = [] (const Point &ref, int n, double side, double rmin, double rmax, double phmin, double phmax) {
+        for (int ix = -n; ix < n; ++ix) {
+            for (int iy = -n; iy < n; ++iy) {
+                Point pt(ref.x() + ix*side, ref.y() + iy*side);
+                if (in_ring(pt, side, rmin, rmax, phmin, phmax)) {
+                    return pt;
+                }
+            }
+        }
+        return ref;
+    };
+
+    std::vector<Point> res;
+    ref = find_seed(ref, int(rmax/lside) + 2, lside, rmin, rmax, phmin, phmax);
+    add_square(ref, res, lside, rmin, rmax, phmin, phmax);
+    return res;
+}
+
+// create the detector
+static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens)
+{
+    xml::DetElement detElem = handle;
+
+    std::string detName = detElem.nameStr();
+    int detID = detElem.id();
+
+    DetElement det(detName, detID);
+    xml::Component dims = detElem.dimensions();
+    xml::Component rads = detElem.child(_Unicode(radiator));
+    xml::Component mir = detElem.child(_Unicode(mirror));
+    xml::Component mcp = detElem.child(_Unicode(mcppmt));
+
+    // dimensions
+    double z0 = dims.z0();
+    double length = dims.length();
+    double rmin = dims.rmin();
+    double rmax1 = dims.attr<double>(_Unicode(rmax1));
+    double rmax2 = dims.attr<double>(_Unicode(rmax2));
+
+    // mirror setting
+    auto mThick = mir.thickness();
+    auto mirZ = mir.attr<double>(_Unicode(zdiff));
+
+    // mcppmt setting
+    auto pRmin = mcp.rmin();
+    auto pRmax = mcp.rmax();
+    auto pThick = mcp.thickness();
+    auto pSize = mcp.attr<double>(_Unicode(module_size));
+    auto pGap = mcp.attr<double>(_Unicode(module_gap));
+    auto pTol = mcp.attr<double>(_Unicode(rtol));
+    auto pZ = mcp.attr<double>(_Unicode(zdiff));
+
+    // materials
+    auto mirMat = desc.material(mir.materialStr());
+    auto gasMat = desc.material(rads.materialStr());
+    auto mcpMat = desc.material(mcp.materialStr());
+
+    // constants
+    auto richCenterAngle = std::atan((rmin + (rmax2 - rmin)/2.)/mirZ);
+    //std::cout << richCenterAngle*180./M_PI << std::endl;
+
+    // an envelope for the detector
+    // use a complicated shape to avoid conflict with the other parts
+    // cone for radiator and the first set of mirrors
+    double halfLength = length/2.;
+    Cone env1(halfLength, rmin, rmax1, rmin, rmax2);
+    // envelope for detection plane
+    // Cone env2(halfLength - pZ/2., rmin, pRmax, rmin, rmax2);
+    Tube env2(rmin, pRmax + pTol + pGap + 1.0*cm, (length - pZ)/2., 0., 2*M_PI);
+
+    UnionSolid envShape(env1, env2, Position(0., 0., pZ));
+
+    Volume envVol(detName + "_envelope", envShape, gasMat);
+    envVol.setVisAttributes(desc.visAttributes(detElem.visStr()));
+
+    // ---------------
+    // spherical mirrors inside it
+    int ilayer = 1;
+
+    // optical surface
+    OpticalSurfaceManager surfMgr = desc.surfaceManager();
+    OpticalSurface mirSurf  = surfMgr.opticalSurface("MirrorOpticalSurface");
+    // mirror slices
+    int imod = 1;
+    for (xml::Collection_t sl(mir, _Unicode(slice)); sl; ++sl, ++imod) {
+        auto focus = sl.attr<double>(_Unicode(focus));
+        auto wphi = sl.attr<double>(_Unicode(phiw));
+        auto rotZ = sl.attr<double>(_Unicode(rotz));
+        auto mRmin = sl.attr<double>(_Unicode(rmin));
+        auto mRmax = sl.attr<double>(_Unicode(rmax));
+        double curve = 0.;
+        if (sl.hasAttr(_Unicode(curve))) {
+            curve = sl.attr<double>(_Unicode(curve));
+        }
+        // geometry of mirror slice
+        PlacedVolume mirPV;
+        Volume mirVol(Form("mirror_v_dummy%d", imod));
+        mirVol.setMaterial(mirMat);
+        mirVol.setVisAttributes(desc.visAttributes(mir.visStr()));
+        // spherical mirror
+        if (curve > 0.) {
+            // somehow geant4 does not support -wphi/2. to wphi/2., so additonal rotation in Z
+            double mTheta1 = std::asin(mRmin/curve);
+            double mTheta2 = std::asin(mRmax/curve);
+            double rotY = -std::asin(focus/curve);
+            mirVol.setSolid(Sphere(curve, curve + mThick, mTheta1, mTheta2, 0., wphi));
+            // action is in a reverse order
+            Transform3D tr = Translation3D(0., 0., mirZ - halfLength)   // move for z position
+                           * RotationZ(rotZ)                            // rotate phi angle
+                           * RotationY(rotY)                            // rotate for focus point
+                           * RotationX(180*degree)
+                           * Translation3D(0., 0., -curve)              // move spherical shell to origin
+                           * RotationZ(-wphi/2.);                       // center phi angle to 0. (-wphi/2., wphi/2.)
+            mirPV = envVol.placeVolume(mirVol, tr);
+        // plane mirror
+        } else {
+            mirVol.setSolid(Tube(mRmin, mRmax, mThick/2.0, 0., wphi));
+            Transform3D tr = Translation3D(0., 0., mirZ - halfLength)   // move for z position
+                           * RotationZ(rotZ)                            // rotate phi angle
+                           * RotationZ(-wphi/2.);                       // center phi angle to 0. (-wphi/2., wphi/2.)
+            mirPV = envVol.placeVolume(mirVol, tr);
+        }
+        mirPV.addPhysVolID("layer", ilayer).addPhysVolID("module", imod);
+        DetElement mirDE(det, Form("Mirror_DE%d", imod), imod);
+        mirDE.setPlacement(mirPV);
+        SkinSurface mirSurfBorder(desc, mirDE, Form("RICHmirror%d", imod), mirSurf, mirVol);
+        mirSurfBorder.isValid();
+    }
+    ilayer++;
+
+    // ---------------
+    // photo-detector unit
+    // Fill the photo-detection plane with square shape MCP-PMTs
+    Box mcpShape1(pSize/2.0, pSize/2.0, pThick/2.0);
+    Volume mcpVol1("mcppmt_v_material", mcpShape1, mcpMat);
+
+    // a thin layer of cherenkov gas for accepting optical photons
+    Box mcpShape(pSize/2.0, pSize/2.0, pThick/2.0 + 0.1*mm);
+    Volume mcpVol("mcppmt_v", mcpShape, gasMat);
+    mcpVol.placeVolume(mcpVol1, Position(0., 0., -0.1*mm));
+
+    mcpVol.setVisAttributes(desc.visAttributes(mcp.visStr()));
+    sens.setType("photoncounter");
+    mcpVol.setSensitiveDetector(sens);
+
+    // photo-detector plane envelope
+    for (size_t ipd = 0; ipd < 6; ++ipd) {
+        double phmin = -M_PI/6.;
+        double phmax = M_PI/6.;
+        Tube pdEnvShape(pRmin - pTol - pGap, pRmax + pTol + pGap, pThick/2.0 + 0.1*cm, phmin, phmax);
+        Volume pdVol("pd_envelope", pdEnvShape, desc.material("AirOptical"));
+        auto points = fill_squares(Point(0., 0.), pSize + pGap, pRmin - pTol - pGap, pRmax + pTol + pGap, phmin, phmax);
+        for (size_t i = 0; i < points.size(); ++i) {
+            auto pt = points[i];
+            auto mcpPV = pdVol.placeVolume(mcpVol, Position(pt.x(), pt.y(), 0.));
+            mcpPV.addPhysVolID("layer", ilayer).addPhysVolID("module", i + 1);
+            DetElement mcpDE(det, Form("MCPPMT_DE%d_%d", ipd + 1, i + 1), i + 1);
+            mcpDE.setPlacement(mcpPV);
+        }
+        Transform3D tr = Translation3D(0., 0., -halfLength + pZ + pThick/2.0)   // move for z position
+                        * RotationZ(ipd*M_PI/3.)        // rotate phi angle
+                        * RotationY(-richCenterAngle);  // rotate to perpendicular position
+        auto pdPV = envVol.placeVolume(pdVol, tr);
+        pdPV.addPhysVolID("layer", ilayer).addPhysVolID("piece", ipd + 1);
+    }
+    Volume motherVol = desc.pickMotherVolume(det);
+    PlacedVolume envPV = motherVol.placeVolume(envVol, Position(0, 0, z0 + halfLength));
+    envPV.addPhysVolID("system", detID);
+    det.setPlacement(envPV);
+
+    return det;
+}
+//@}
+
+// clang-format off
+DECLARE_DETELEMENT(refdet_ForwardRICH, createDetector)
+