diff --git a/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py b/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py
index 6bf8a8e7cf1e59bea6b6bb6abf0ef9f3900425b4..15c8e1c942aa69ff3d61edc1b4f03a1461c179d0 100644
--- a/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py
+++ b/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py
@@ -149,6 +149,10 @@ digiMuon.MuonBarrelTrackerHits = "MuonBarrelTrackerHits"
 digiMuon.MuonEndcapTrackerHits = "MuonEndcapTrackerHits"
 digiMuon.WriteNtuple = 0
 digiMuon.OutFileName = "Digi_MUON.root"
+digiMuon.SiPMEff = 1
+digiMuon.EdepMin = 0.0001
+digiMuon.HitEdepMin = 0.000001
+digiMuon.HitEdepMax = 0.1
 #########################################
 
 ################
diff --git a/Digitization/DigiMuon/src/MuonDigiAlg.cpp b/Digitization/DigiMuon/src/MuonDigiAlg.cpp
index 347cb6c8c82d48cfb99437aec490509d1e36ad7d..0523a7e5d58b0f094c85a4c040aa8ed6e15e6266 100644
--- a/Digitization/DigiMuon/src/MuonDigiAlg.cpp
+++ b/Digitization/DigiMuon/src/MuonDigiAlg.cpp
@@ -55,7 +55,7 @@ MuonDigiAlg::MuonDigiAlg(const std::string& name, ISvcLocator* svcLoc)
 StatusCode MuonDigiAlg::initialize()
 {
   // set rand seed;
-  rand_muon.SetSeed(123456);
+  m_randSvc = service<IRndmGenSvc>("RndmGenSvc");
 
   // 
   if(_writeNtuple)
@@ -86,6 +86,8 @@ StatusCode MuonDigiAlg::initialize()
     m_tree->Branch("cell_strip", cell_strip, "cell_strip[n_cell]/I");
     m_tree->Branch("cell_fe", cell_fe, "cell_fe[n_cell]/I");
     m_tree->Branch("cell_env", cell_env, "cell_env[n_cell]/I");
+    m_tree->Branch("cell_superlayernumber", &cell_superlayernumber, "cell_superlayernumber/I");
+    m_tree->Branch("cell_pt", &cell_pt, "cell_pt/I");
   }
 
 
@@ -108,19 +110,19 @@ StatusCode MuonDigiAlg::initialize()
     return StatusCode::FAILURE;
   }
 
-  std::string readout_name1 = m_inputMuonBarrel.objKey(); 
-  debug() << "Readout name: " << readout_name1 << endmsg;
-  m_decoder1 = m_geosvc->getDecoder(readout_name1);
-  if(!m_decoder1)
+  std::string readout_name_barrel = m_inputMuonBarrel.objKey(); 
+  debug() << "Readout name: " << readout_name_barrel << endmsg;
+  m_decoder_barrel = m_geosvc->getDecoder(readout_name_barrel);
+  if(!m_decoder_barrel)
   {
     error() << "Failed to get the decoder. " << endmsg;
     return StatusCode::FAILURE;
   }
 
-  std::string readout_name2 = m_inputMuonEndcap.objKey(); 
-  debug() << "Readout name: " << readout_name2 << endmsg;
-  m_decoder2 = m_geosvc->getDecoder(readout_name2);
-  if(!m_decoder2)
+  std::string readout_name_endcap = m_inputMuonEndcap.objKey(); 
+  debug() << "Readout name: " << readout_name_endcap << endmsg;
+  m_decoder_endcap = m_geosvc->getDecoder(readout_name_endcap);
+  if(!m_decoder_endcap)
   {
     error() << "Failed to get the decoder. " << endmsg;
     return StatusCode::FAILURE;
@@ -135,451 +137,122 @@ StatusCode MuonDigiAlg::initialize()
 
 StatusCode MuonDigiAlg::execute()
 {
-  for(int muonmode = 0; muonmode<2; muonmode++)
+  const edm4hep::SimTrackerHitCollection* STHCol;
+//MuonBarrelRun:
+  Clear();
+  trkhitVec = m_outputMuonBarrel.createAndPut();
+  STHCol = nullptr;
+  try 
   {
-    if(muonmode == 0)//muon barrel run
+    STHCol = m_inputMuonBarrel.get();
+  }
+  catch(GaudiException &e)
+  {
+    debug() << "Collection " << m_inputMuonBarrel.fullKey() << " is unavailable in event " << m_nEvt << endmsg;
+  }
+  if(STHCol->size()==0) goto MuonEndcapRun;
+
+  for(auto simhit : *STHCol)
+  {
+    GetSimHit(simhit, m_decoder_barrel);
+    Fe = m_decoder_barrel->get(cellid, "Fe");
+    if ( Edep > m_hit_Edep_max || Edep < m_hit_Edep_min ) continue;                 // Cut1: Edep of one hit
+    if ( xydist < 5162 && std::abs(mcppos[2]) < 5475 || abspdgid != 13 ) continue;  // Cut2: The particle decays in the Muon Detector or is not a muon
+    std::cout<<"Barrel Simulation Hit::::::: "<<Fe<<" "<<slayer<<" "<<layer<<"        "<<mcppos[0]<<" "<<mcppos[1]<<" "<<mcppos[2]<<" "<<abspdgid<<std::endl;
+    hit_sipm_length = Gethit_sipm_length_Barrel();
+    EdeptoADC();
+    SaveData_mapcell();
+  }
+
+  if(map_cell_edep.size()==0) goto MuonEndcapRun;
+  Cut3();
+
+  for (const auto& item1 : map_cell_edep) 
+  {
+    key1 = item1.first;
+    if(!Mapcell_todata(all_message1, key1)) continue;
+    Save_pos(1);
+    anotherlayer_cell_num = 0;   
+    for (const auto& item2 : map_cell_edep) 
     {
-      Clear();
-      if(m_MuonMode == 2) continue;
-      trkhitVec = m_outputMuonBarrel.createAndPut();
-      //auto assVec = m_assMuonBarrel.createAndPut();
-
-      const edm4hep::SimTrackerHitCollection* STHCol = nullptr;
-      try 
-      {
-        STHCol = m_inputMuonBarrel.get();
-      }
-      catch(GaudiException &e)
-      {
-        debug() << "Collection " << m_inputMuonBarrel.fullKey() << " is unavailable in event " << m_nEvt << endmsg;
-        continue;
-      }
-      if(STHCol->size()==0) continue;
-      debug() << m_inputMuonBarrel.fullKey() << " has SimTrackerHit "<< STHCol->size() << endmsg;
-      
-      // number of strips parallel to beam direction 
-      // in each slayer, each strip width=4cm, so 
-      int strip_length[6] = {26, 38, 50, 62, 74, 86};
-
-      // define variables to be repeatedly used later
-      std::array<unsigned long long, 2> key;
-      int pdgid;
-      unsigned long long cellid, abspdgid; 
-      double Edep, ADC, ADCmean;
-      int layer, slayer, strip, Fe, Env;
-      edm4hep::Vector3d pos;
-      dd4hep::Position ddpos;
-      // loop over all hits
-      for(auto simhit : *STHCol)
-      {
-        auto mcp = simhit.getMCParticle();
-        cellid = simhit.getCellID();
-        pdgid = mcp.getPDG();
-        abspdgid = std::abs(mcp.getPDG());
-        key = std::array<unsigned long long, 2>{cellid, abspdgid};
-        Edep   = simhit.getEDep();//GeV
-        layer  = m_decoder1->get(cellid, "Layer");
-        slayer = m_decoder1->get(cellid, "Superlayer");
-        strip  = m_decoder1->get(cellid, "Stripe");
-        Fe     = m_decoder1->get(cellid, "Fe");
-        Env    = m_decoder1->get(cellid, "Env");
-        pos = simhit.getPosition();
-        ddpos = m_cellIDConverter->position(cellid);
-        debug() << "Position::   " << ddpos.x() << " " << ddpos.y() << " " << ddpos.z() << endmsg;
-
-        // if not satisfy energy requirement, skip this hit
-        if ( Edep>0.1 || Edep<0.000001 ) continue;
-        
-        //calculate hit strip length
-        double hit_strip_length = std::sqrt((ddpos.x()-pos[0]*0.1)*(ddpos.x()-pos[0]*0.1)+(ddpos.y()-pos[1]*0.1)*(ddpos.y()-pos[1]*0.1)+(ddpos.z()-pos[2]*0.1)*(ddpos.z()-pos[2]*0.1));
-        double hit_sipm_length;
-        
-        if(layer == 1)
-        {
-          int tempnum = Env + slayer;
-          if(tempnum%2 == 0)
-          {
-            // 115 is the number of strips parpendicular 
-            // to the beam axis in long-half-barrel
-            hit_sipm_length = (115 * 4.0)/2 - hit_strip_length;
-          }
-          else
-          {
-            // 106 is the number of strips parpendicular 
-            // to the beam axis in short-half-barrel
-            hit_sipm_length = (106 * 4.0)/2 - hit_strip_length;
-          }
-        } 
-        if(layer == 2)
-        {
-          // number of strips parallel to beam direction 
-          // in each slayer, each strip width=4cm, so 
-          // the number * 4 cm gives the length of strips 
-          // in each slayer parpendicular to the beam axis
-          hit_sipm_length = (strip_length[slayer-1] * 4)/2 - hit_strip_length;
-        }
-
-        // digitize to ADC 
-        ADCmean = 34*Edep*47.09/(23*0.00141);//mV
-        if(hit_sipm_length>10)
-        {
-          ADCmean = (16.0813*std::exp(-1*hit_sipm_length/50.8147)+19.5474)*Edep*47.09/(23*0.00141);//mV
-        }
-        ADC = rand_muon.Landau(ADCmean,7.922);
-        if(ADC<0)
-        {
-          ADC = 0;
-        }
-
-        // fill the cell loop
-        map_cell_edep[key] += Edep;
-        map_cell_adc[key] += ADC;
-        map_cell_layer[key] = layer;
-        map_cell_slayer[key] = slayer;
-        map_cell_strip[key] = strip;
-        map_cell_fe[key] = Fe;
-        map_cell_env[key] = Env;
-        map_cell_pos[key] = pos;
-        map_cell_pdgid[key] = pdgid;
-
-        // write to tree
-        if(_writeNtuple)
-        {
-          hit_cellid[n_hit] = cellid;
-          hit_posx[n_hit] = pos[0];
-          hit_posy[n_hit] = pos[1];
-          hit_posz[n_hit] = pos[2];
-          hit_edep[n_hit] = Edep;
-          hit_layer[n_hit] = layer;
-          hit_slayer[n_hit] = slayer;
-          hit_strip[n_hit] = strip;
-          hit_fe[n_hit] = Fe;
-          hit_env[n_hit] = Env;
-          n_hit++;
-        }
-        
-      }
-      std::array<unsigned long long, 2> key1;
-      unsigned long long cellid1; 
-      int layer1, slayer1, strip1, Fe1, Env1, pdgid1;
-      edm4hep::Vector3d pos1;
-      dd4hep::Position ddpos1;
-
-      std::array<unsigned long long, 2> key2;
-      unsigned long long cellid2; 
-      int layer2, slayer2, strip2, Fe2, Env2, pdgid2;
-      edm4hep::Vector3d pos2;
-      dd4hep::Position ddpos2;
-
-      if(map_cell_edep.size()==0) continue;
-      //some criteria
-      for(const auto& item : map_cell_edep)
-      {
-        key = item.first;
-        if (map_cell_edep[key] < m_EdepMin || rand_muon.Uniform(0, 1)>m_hitEff || map_cell_adc[key] == 0)
-        {
-          map_cell_edep[key] = 0;
-        }
-      }
-
-      double muonhitx, muonhity, muonhitz;
-      double Hit_max, Hit_min;
-
-      // loop over all cells 
-      for (const auto& item1 : map_cell_edep) 
-      {
-        key1 = item1.first;
-        cellid1 = key1[0];
-        Edep = map_cell_edep[key1];
-        if ( Edep < 0.0001 ) continue;  
-        int anotherlayer_cell_num = 0;
-
-        ADC = map_cell_adc[key1];
-        layer1 = map_cell_layer[key1];
-        slayer1 = map_cell_slayer[key1];
-        strip1 = map_cell_strip[key1];
-        Fe1 = map_cell_fe[key1];
-        Env1 = map_cell_env[key1];
-        pos1 = map_cell_pos[key1];
-        pdgid1 = map_cell_pdgid[key1];
-        ddpos1 = m_cellIDConverter->position(cellid1);
-
-        for (const auto& item2 : map_cell_edep) 
-        {
-          key2 = item2.first;
-          cellid2 = key2[0];
-          Edep = map_cell_edep[key2];
-          if ( Edep < 0.0001 ) continue;  
-
-          layer2 = map_cell_layer[key2];
-          slayer2 = map_cell_slayer[key2];
-          strip2 = map_cell_strip[key2];
-          Fe2 = map_cell_fe[key2];
-          Env2 = map_cell_env[key2];
-          pos2 = map_cell_pos[key2];
-          pdgid2 = map_cell_pdgid[key2];
-          ddpos2 = m_cellIDConverter->position(cellid2);    
-
-          if(slayer1!=slayer2 || Fe1!=Fe2 || Env1!=Env2 || layer1==layer2 || layer1==2) continue;//layer1 = 1
-          Hit_min = pos1[2]*0.1-12;
-          Hit_max = pos1[2]*0.1+12;
-          if(ddpos2.z()<Hit_min || ddpos2.z()>Hit_max) continue;
-          anotherlayer_cell_num++;
-          map_muonhit[anotherlayer_cell_num] = ddpos2.z(); 
-          map_pdgid[anotherlayer_cell_num] = -1;      
-          if(std::abs(pos1[0]-pos2[0])>40 && std::abs(pos1[1]-pos2[1])>40 && std::abs(pos1[2]-pos2[2])>40) continue;
-          map_pdgid[anotherlayer_cell_num] = pdgid2;
-        }
-
-        if(anotherlayer_cell_num == 0) continue;
-        if(anotherlayer_cell_num > 0)
-        {
-          for(int i=1; i<=anotherlayer_cell_num; i++)
-          {
-              muonhitx = ddpos1.x();
-              muonhity = ddpos1.y();
-              muonhitz = map_muonhit[i];
-            // store to raw hit
-            edm4hep::MutableTrackerHit trkHit;
-            int true_pdgid = 0;
-            if(std::abs(pdgid1) == 13 && std::abs(map_pdgid[i]) == 13)
-            {
-              true_pdgid = 1;//pdgid->true muon hit
-            }
-            if(map_pdgid[i]==-1)
-            {
-              true_pdgid = 2;//ghost point
-            }
-            pos = edm4hep::Vector3d(muonhitx*10,muonhity*10,muonhitz*10);//mm
-            trkHit.setEDep(ADC);
-            trkHit.setQuality(true_pdgid);
-            trkHit.setCellID(cellid1);
-            trkHit.setPosition(pos);
-            trkhitVec->push_back( trkHit );
-          }
-        }
-        // write for out ntuple
-        if(_writeNtuple)
-        {
-          cell_cellid[n_cell] = cellid;
-          cell_edep[n_cell] = Edep;
-          cell_adc[n_cell] = ADC;
-          cell_posx[n_cell] = pos[0];
-          cell_posy[n_cell] = pos[1];
-          cell_posz[n_cell] = pos[2];
-          cell_layer[n_cell] = layer;
-          cell_slayer[n_cell] = slayer;
-          cell_strip[n_cell] = strip;
-          cell_fe[n_cell] = Fe;
-          cell_env[n_cell] = Env;
-          n_cell++;
-        }
-      }
-      if(_writeNtuple)
-      {
-        m_tree->Fill();
-      }
+      key2 = item2.first;
+      if(!Mapcell_todata(all_message2, key2)) continue;
+      if(all_message1[1]!=all_message2[1] || all_message1[2]!=all_message2[2] || all_message1[3]!=all_message2[3] || all_message1[0]==all_message2[0] || all_message1[0]==2) continue;
+      Save_pos(2);
+      std::cout<<"::::::  "<<cellid1<<" "<<key1[0]<<std::endl;
+      std::cout<<ddpos1.x()<<" "<<ddpos1.y()<<std::endl;
+      std::cout<<pos1[0]<<" "<<pos1[1]<<std::endl;
+      Renew_strip(key1, key2);
+      Find_anotherlayer(2, pos1, pos2, ddpos2.z(), all_message2[5]);
     }
-    if(muonmode == 1)//muon endcap run
+
+    if(anotherlayer_cell_num == 0) continue;
+    for(int i=1; i<=anotherlayer_cell_num; i++)
     {
-      Clear();
-      if(m_MuonMode == 1) continue;
-      trkhitVec = m_outputMuonEndcap.createAndPut();
-      const edm4hep::SimTrackerHitCollection* STHCol = nullptr;
-      try 
-      {
-        STHCol = m_inputMuonEndcap.get();
-      }
-      catch(GaudiException &e)
-      {
-        debug() << "Collection " << m_inputMuonEndcap.fullKey() << " is unavailable in event " << m_nEvt << endmsg;
-        continue;
-      }
-      if(STHCol->size()==0) continue;
-      debug() << m_inputMuonEndcap.fullKey() << " has SimTrackerHit "<< STHCol->size() << endmsg;
-
-      double endcap_strip_length[193] = {2.12, 2.12, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.19, 2.22,
-                                         2.24, 2.28, 2.32, 2.37, 2.45, 2.65, 2.64, 2.63, 2.62, 2.61,
-                                         2.60, 2.59, 2.57, 2.56, 2.54, 2.53, 2.51, 2.50, 2.48, 2.46, 
-                                         2.44, 2.42, 2.40, 2.38, 2.36, 2.33, 2.31, 2.28, 2.26, 2.23,
-                                         2.20, 2.17, 2.14, 2.11, 2.07, 2.04, 2.00, 1.97, 1.93, 1.89, 
-                                         1.84, 1.80, 1.75, 1.70, 1.65, 1.60, 1.54, 1.48, 1.42, 1.35, 
-                                         1.28, 1.20, 1.12, 1.02, 0.92, 0.80, 0.65, 0.46, 2.20, 2.20,
-                                         2.20, 2.20, 2.20, 2.20, 2.20, 2.21, 2.21, 2.21, 2.21, 2.22,
-                                         2.22, 2.22, 2.23, 2.23, 2.23, 2.24, 2.24, 2.25, 2.25, 2.26,
-                                         2.26, 2.27, 2.28, 2.28, 2.29, 2.30, 2.31, 2.32, 2.32, 2.33,
-                                         2.34, 2.35, 2.36, 2.38, 2.39, 2.40, 2.41, 2.43, 2.44, 2.45,
-                                         2.47, 2.49, 2.50, 2.52, 2.54, 2.56, 2.58, 2.60, 2.62, 2.65, 
-                                         2.67, 2.70, 2.73, 2.76, 2.79, 2.82, 2.86, 2.90, 2.94, 2.99,
-                                         3.04, 3.10, 3.16, 3.23, 3.31, 3.41, 3.53, 3.70, 4.14, 4.12, 
-                                         4.09, 4.06, 4.03, 4.00, 3.97, 3.94, 3.91, 3.87, 3.84, 3.81, 
-                                         3.77, 3.74, 3.70, 3.67, 3.63, 3.59, 3.55, 3.51, 3.47, 3.43, 
-                                         3.38, 3.34, 3.30, 3.25, 3.20, 3.15, 3.10, 3.05, 3.00, 2.95, 
-                                         2.89, 2.83, 2.77, 2.71, 2.65, 2.58, 2.52, 2.45, 2.37, 2.30, 
-                                         2.22, 2.14, 2.05, 1.96, 1.86, 1.76, 1.65, 1.53, 1.40, 1.25, 
-                                         1.09, 0.89, 0.63};
-
-
-      // define variables to be repeatedly used later
-      std::array<unsigned long long, 2> key;
-      int pdgid;
-      unsigned long long cellid, abspdgid; 
-      double Edep, ADC, ADCmean;
-      int layer, slayer, strip, Env, Endcap;
-      edm4hep::Vector3d pos;
-      dd4hep::Position ddpos;
-      // loop over all hits
-      for(auto simhit : *STHCol)
-      {
-        auto mcp = simhit.getMCParticle();
-        cellid = simhit.getCellID();
-        pdgid = mcp.getPDG();
-        abspdgid = std::abs(mcp.getPDG());
-        key = std::array<unsigned long long, 2>{cellid, abspdgid};
-        Edep   = simhit.getEDep();//GeV
-        layer  = m_decoder2->get(cellid, "Layer");
-        slayer = m_decoder2->get(cellid, "Superlayer");
-        strip  = m_decoder2->get(cellid, "Stripe");
-        Endcap = m_decoder2->get(cellid, "Endcap");
-        Env    = m_decoder2->get(cellid, "Env");
-        pos = simhit.getPosition();
-        ddpos = m_cellIDConverter->position(cellid);
-        debug() << "Position::   " << ddpos.x() << " " << ddpos.y() << " " << ddpos.z() << endmsg;
-
-        // if not satisfy energy requirement, skip this hit
-        if ( Edep>0.1 || Edep<0.000001 ) continue;
-
-        //calculate hit strip length
-        double hit_strip_length = std::sqrt((ddpos.x()-pos[0]*0.1)*(ddpos.x()-pos[0]*0.1)+(ddpos.y()-pos[1]*0.1)*(ddpos.y()-pos[1]*0.1)+(ddpos.z()-pos[2]*0.1)*(ddpos.z()-pos[2]*0.1));
-        strip--; // strip id begin at 1
-        double hit_sipm_length = endcap_strip_length[strip] * 0.5 * 100 - hit_strip_length;//cm
-
-        // digitize to ADC 
-        ADCmean = 34*Edep*47.09/(23*0.00141);//mV
-        if(hit_sipm_length>10)
-        {
-          ADCmean = (16.0813*std::exp(-1*hit_sipm_length/50.8147)+19.5474)*Edep*47.09/(23*0.00141);//mV
-        }
-        ADC = rand_muon.Landau(ADCmean,7.922);
-        if(ADC<0)
-        {
-          ADC = 0;
-        }
-
-        map_cell_edep[key] += Edep;
-        map_cell_adc[key] += ADC;
-        map_cell_layer[key] = layer;
-        map_cell_slayer[key] = slayer;
-        map_cell_strip[key] = strip;
-        map_cell_fe[key] = Endcap;
-        map_cell_env[key] = Env;
-        map_cell_pos[key] = pos;
-        map_cell_pdgid[key] = pdgid;
-      }
-
-      std::array<unsigned long long, 2> key1;
-      unsigned long long cellid1; 
-      int layer1, slayer1, strip1, Fe1, Env1, pdgid1;
-      edm4hep::Vector3d pos1;
-      dd4hep::Position ddpos1;
-
-      std::array<unsigned long long, 2> key2;
-      unsigned long long cellid2; 
-      int layer2, slayer2, strip2, Fe2, Env2, pdgid2;
-      edm4hep::Vector3d pos2;
-      dd4hep::Position ddpos2;
-
-      if(map_cell_edep.size()==0) continue;
-
-      for(const auto& item : map_cell_edep)
-      {
-        key = item.first;
-        if (map_cell_edep[key] < m_EdepMin || rand_muon.Uniform(0, 1)>m_hitEff || map_cell_adc[key] == 0)
-        {
-          map_cell_edep[key] = 0;
-        }
-      }
-
-      double muonhitx, muonhity, muonhitz;
-      double Hit_max, Hit_min;
-
-      // loop over all cells 
-      for (const auto& item1 : map_cell_edep) 
-      {
-        key1 = item1.first;
-        cellid1 = key1[0];
-        Edep = map_cell_edep[key1];
-        if ( Edep < 0.0001 ) continue;  
-        int anotherlayer_cell_num = 0;
-
-        ADC = map_cell_adc[key1];
-        layer1 = map_cell_layer[key1];
-        slayer1 = map_cell_slayer[key1];
-        strip1 = map_cell_strip[key1];
-        Fe1 = map_cell_fe[key1];//endcap
-        Env1 = map_cell_env[key1];
-        pos1 = map_cell_pos[key1];
-        pdgid1 = map_cell_pdgid[key1];
-        ddpos1 = m_cellIDConverter->position(cellid1);
-
-        for (const auto& item2 : map_cell_edep) 
-        {
-          key2 = item2.first;
-          cellid2 = key2[0];
-          Edep = map_cell_edep[key2];
-          if ( Edep < 0.0001 ) continue;  
-
-          layer2 = map_cell_layer[key2];
-          slayer2 = map_cell_slayer[key2];
-          strip2 = map_cell_strip[key2];
-          Fe2 = map_cell_fe[key2];//endcap
-          Env2 = map_cell_env[key2];
-          pos2 = map_cell_pos[key2];
-          pdgid2 = map_cell_pdgid[key2];
-          ddpos2 = m_cellIDConverter->position(cellid2);    
-
-          if(Fe1!=Fe2 || slayer1!=slayer2 || layer1==layer2 || layer1==2) continue;
-          if(std::abs(Env2-Env1) == 2) continue;
-          Hit_min = pos1[0]*0.1-12;
-          Hit_max = pos1[0]*0.1+12;
-          if(ddpos2.x()<Hit_min || ddpos2.x()>Hit_max) continue;
-          anotherlayer_cell_num++;
-          map_muonhit[anotherlayer_cell_num] = ddpos2.x();      
-          map_pdgid[anotherlayer_cell_num] = -1;      
-          if(std::abs(pos1[0]-pos2[0])>40 && std::abs(pos1[1]-pos2[1])>40 && std::abs(pos1[2]-pos2[2])>40) continue;
-          map_pdgid[anotherlayer_cell_num] = pdgid2;         
-        }
-        if(anotherlayer_cell_num == 0) continue;
-        if(anotherlayer_cell_num > 0)
-        {
-          for(int i=1; i<=anotherlayer_cell_num; i++)
-          {
-            muonhitx = map_muonhit[i];
-            muonhity = ddpos1.y();
-            muonhitz = ddpos1.z();
-            // store to raw hit
-            edm4hep::MutableTrackerHit trkHit;
-            int true_pdgid = 0;
-            if(std::abs(pdgid1) == 13 && std::abs(map_pdgid[i]) == 13)
-            {
-              true_pdgid = 1;//pdgid->true muon hit
-            }
-            if(map_pdgid[i]==-1)
-            {
-              true_pdgid = 2;//ghost point
-            }
-            pos = edm4hep::Vector3d(muonhitx*10,muonhity*10,muonhitz*10);
-            trkHit.setEDep(ADC);
-            trkHit.setQuality(true_pdgid);
-            trkHit.setCellID(cellid1);
-            trkHit.setPosition(pos);
-            trkhitVec->push_back( trkHit );
-          }
-        }
-      }
+      true_pdgid = 0;
+      true_pdgid = Get_true_pdgid(i, all_message1[5]);
+      pos = edm4hep::Vector3d(ddpos1.x()*10,ddpos1.y()*10,map_muonhit[i]*10);//mm
+std::cout<<pos[0]<<" "<<pos[1]<<" "<<pos[2]<<std::endl;
+      Save_trkhit(trkhitVec, key1, true_pdgid, cellid1, pos);
     }
   }
+  Save_onelayer_signal(trkhitVec);
 
+MuonEndcapRun:
+  Clear();
+  trkhitVec = m_outputMuonEndcap.createAndPut();
+  STHCol = nullptr;
+  try 
+  {
+    STHCol = m_inputMuonEndcap.get();
+  }
+  catch(GaudiException &e)
+  {
+    debug() << "Collection " << m_inputMuonEndcap.fullKey() << " is unavailable in event " << m_nEvt << endmsg;
+  }
+  if(STHCol->size()==0) return StatusCode::SUCCESS;
+
+  for(auto simhit : *STHCol)
+  {
+    GetSimHit(simhit, m_decoder_endcap);
+    Fe = m_decoder_endcap->get(cellid, "Endcap");
+    if ( Edep > m_hit_Edep_max || Edep < m_hit_Edep_min ) continue;                 // Cut1: Edep of one hit
+    if ( xydist < 5162 && std::abs(mcppos[2]) < 5475 || abspdgid != 13 ) continue;  // Cut2: The particle decays in the Muon Detector or is not a muon
+    std::cout<<"Endcap Simulation Hit::::::: "<<Env<<" "<<slayer<<" "<<layer<<"          "<<mcppos[0]<<" "<<mcppos[1]<<" "<<mcppos[2]<<" "<<abspdgid<<std::endl;
+    hit_sipm_length = Gethit_sipm_length_Endcap();
+    EdeptoADC();
+    SaveData_mapcell();
+  }  
+
+  if(map_cell_edep.size()==0) return StatusCode::SUCCESS;
+  Cut3();
+
+  for (const auto& item1 : map_cell_edep) 
+  {
+    key1 = item1.first;
+    if(!Mapcell_todata(all_message1, key1)) continue;
+    Save_pos(1);
+    anotherlayer_cell_num = 0;  
+    for (const auto& item2 : map_cell_edep) 
+    {
+      key2 = item2.first;
+      if(!Mapcell_todata(all_message2, key2)) continue;
+      if(all_message1[1]!=all_message2[1] || all_message1[3]!=all_message2[3] || all_message1[0]==all_message2[0] || all_message1[0]==2) continue;
+      if(std::abs(all_message1[2] - all_message2[2]) == 2) continue;
+      Save_pos(2);
+      Renew_strip(key1, key2);
+      Find_anotherlayer(0, pos1, pos2, ddpos2.x(), all_message2[5]);  
+    }
+    if(anotherlayer_cell_num == 0) continue;
+    for(int i=1; i<=anotherlayer_cell_num; i++)
+    {
+      true_pdgid = 0;
+      true_pdgid = Get_true_pdgid(i, all_message1[5]);
+      pos = edm4hep::Vector3d(map_muonhit[i]*10,ddpos1.y()*10,ddpos1.z()*10);//mm
+      Save_trkhit(trkhitVec, key1, true_pdgid, cellid1, pos);      
+    }
+  }
+  Save_onelayer_signal(trkhitVec);
 
   m_nEvt++;
   return StatusCode::SUCCESS;
@@ -615,3 +288,181 @@ void MuonDigiAlg::Clear()
   map_cell_pdgid.clear();
   map_pdgid.clear();
 }
+
+void MuonDigiAlg::GetSimHit(edm4hep::SimTrackerHit _simhit, dd4hep::DDSegmentation::BitFieldCoder* _m_decoder)
+{
+  auto mcp = _simhit.getMCParticle();
+  cellid = _simhit.getCellID();
+  mcppos = mcp.getEndpoint();
+  pdgid = mcp.getPDG();    
+  abspdgid = std::abs(mcp.getPDG());    
+  key = std::array<unsigned long long, 2>{cellid, abspdgid};
+  Edep   = _simhit.getEDep();//GeV
+  layer  = _m_decoder->get(cellid, "Layer");
+  slayer = _m_decoder->get(cellid, "Superlayer");
+  strip  = _m_decoder->get(cellid, "Stripe");
+  Env    = _m_decoder->get(cellid, "Env");
+  pos = _simhit.getPosition();
+  ddpos = m_cellIDConverter->position(cellid);  
+  xydist = std::sqrt(mcppos[0]*mcppos[0]+mcppos[1]*mcppos[1]);
+}
+
+double MuonDigiAlg::Gethit_sipm_length_Barrel()
+{
+  //calculate hit strip length
+  hit_strip_length = std::sqrt((ddpos.x()-pos[0]*0.1)*(ddpos.x()-pos[0]*0.1)+
+                               (ddpos.y()-pos[1]*0.1)*(ddpos.y()-pos[1]*0.1)+
+                               (ddpos.z()-pos[2]*0.1)*(ddpos.z()-pos[2]*0.1));
+  if(layer == 1)
+  {
+    int tempnum = Env + slayer;
+    if(tempnum%2 == 0)
+    {
+      // 115 is the number of strips perpendicular 
+      // to the beam axis in long-half-barrel
+      return (115.5 * 4.0)/2 - hit_strip_length;
+    }
+    else
+    {
+      // 106 is the number of strips perpendicular 
+      // to the beam axis in short-half-barrel
+      return (106.5 * 4.0)/2 - hit_strip_length;
+    }
+  } 
+  if(layer == 2)
+  {
+    // number of strips parallel to beam direction 
+    // in each slayer, each strip width=4cm, so 
+    // the number * 4 cm gives the length of strips 
+    // in each slayer parpendicular to the beam axis
+    return (strip_length[slayer-1] * 4)/2 - hit_strip_length;
+  }  
+}
+
+double MuonDigiAlg::Gethit_sipm_length_Endcap()
+{
+  //calculate hit strip length
+  hit_strip_length = std::sqrt((ddpos.x()-pos[0]*0.1)*(ddpos.x()-pos[0]*0.1)+(ddpos.y()-pos[1]*0.1)*(ddpos.y()-pos[1]*0.1)+(ddpos.z()-pos[2]*0.1)*(ddpos.z()-pos[2]*0.1));
+  strip--; // strip id begin at 1
+  return endcap_strip_length[strip] * 0.5 * 100 - hit_strip_length;//cm  
+}
+
+void MuonDigiAlg::EdeptoADC()
+{
+  // digitize to ADC 
+  ADCmean = 34*Edep*47.09/(23*0.00141);//mV
+  if(hit_sipm_length>10)
+  {
+    ADCmean = (16.0813*std::exp(-1*hit_sipm_length/50.8147)+19.5474)*Edep*47.09/(23*0.00141);//mV
+  }
+  ADC = m_randSvc->generator(Rndm::Landau(ADCmean,7.922))->shoot();
+  if(ADC<0)
+  {
+    ADC = 0;
+  }
+}
+
+void MuonDigiAlg::SaveData_mapcell()
+{
+  // fill the cell loop
+  map_cell_edep[key] += Edep;
+  map_cell_adc[key] += ADC;
+  map_cell_layer[key] = layer;
+  map_cell_slayer[key] = slayer;
+  map_cell_strip[key] = strip;
+  map_cell_fe[key] = Fe;
+  map_cell_env[key] = Env;
+  map_cell_pos[key] = pos;
+  map_cell_pdgid[key] = pdgid;
+}
+
+bool MuonDigiAlg::Mapcell_todata(int _message[6], std::array<unsigned long long, 2> _key)
+{
+  Edep = map_cell_edep[_key];
+  if ( Edep < m_EdepMin ) return false;  
+  _message[0] = map_cell_layer[_key];
+  _message[1] = map_cell_slayer[_key];
+  _message[2] = map_cell_env[_key];
+  _message[3] = map_cell_fe[_key];
+  _message[4] = map_cell_strip[_key];
+  _message[5] = map_cell_pdgid[_key];
+  return true;
+}
+
+void MuonDigiAlg::Cut3()
+{
+  //some criteria
+  for(const auto& item : map_cell_edep)
+  {
+    key = item.first;
+    if (map_cell_edep[key] < m_EdepMin || m_randSvc->generator(Rndm::Flat(0, 1))->shoot() > m_hitEff || map_cell_adc[key] == 0)
+    {
+      map_cell_edep[key] = 0;
+    }
+  }
+}
+
+void MuonDigiAlg::Save_trkhit(edm4hep::TrackerHitCollection* _trkhitVec, std::array<unsigned long long, 2> _key, int _pdgid, unsigned long long _cellid, edm4hep::Vector3d _pos)
+{
+  edm4hep::MutableTrackerHit trkHit;
+  trkHit.setEDep(map_cell_adc[_key]);
+  trkHit.setQuality(_pdgid);
+  trkHit.setCellID(_cellid);
+  trkHit.setPosition(_pos);
+  _trkhitVec->push_back( trkHit );
+}
+
+void MuonDigiAlg::Renew_strip(std::array<unsigned long long, 2> _key1, std::array<unsigned long long, 2> _key2)
+{
+  map_cell_strip[_key1] = -1;
+  map_cell_strip[_key2] = -1;
+}
+
+void MuonDigiAlg::Find_anotherlayer(int _i, edm4hep::Vector3d _pos1, edm4hep::Vector3d _pos2, double _ddposi, int _pdgid)
+{
+  Hit_min = _pos1[_i]*0.1-12;//10cm+2cm
+  Hit_max = _pos1[_i]*0.1+12;
+  if(_ddposi<Hit_min || _ddposi>Hit_max) return;
+  anotherlayer_cell_num++;
+  map_muonhit[anotherlayer_cell_num] = _ddposi; 
+  map_pdgid[anotherlayer_cell_num] = -1;      
+  if(std::abs(_pos1[0]-_pos2[0])>40 && std::abs(_pos1[1]-_pos2[1])>40 && std::abs(_pos1[2]-_pos2[2])>40) return;
+  map_pdgid[anotherlayer_cell_num] = _pdgid;
+}
+
+int MuonDigiAlg::Get_true_pdgid(int _i, int _pdgid)
+{
+  if(std::abs(_pdgid) == 13 && std::abs(map_pdgid[_i]) == 13) { return 1; } //pdgid->true muon hit
+  if(map_pdgid[_i]==-1) { return 2; } //ghost point
+}
+
+void MuonDigiAlg::Save_onelayer_signal(edm4hep::TrackerHitCollection* _trkhitVec)
+{
+  for (const auto& _item : map_cell_strip) 
+  {
+    if(_item.second == -1) continue;
+    key = _item.first;
+    cellid = key[0];
+    Edep = map_cell_edep[key];
+    if ( Edep < m_EdepMin ) continue;  
+    ddpos = m_cellIDConverter->position(cellid);
+    pos = edm4hep::Vector3d(ddpos.x()*10,ddpos.y()*10,ddpos.z()*10);//mm
+    Save_trkhit(_trkhitVec, key, 3, cellid1, pos);  //just one layer signal in a superlayer
+  }
+}
+
+void MuonDigiAlg::Save_pos(int _i)
+{
+  if(_i == 1)
+  {
+    cellid1 = key1[0];
+    ddpos1 = m_cellIDConverter->position(cellid1);
+    pos1 = map_cell_pos[key1];    
+  }
+  if(_i == 2)
+  {
+    cellid2 = key2[0];
+    ddpos2 = m_cellIDConverter->position(cellid2);
+    pos2 = map_cell_pos[key2];    
+  }  
+}
diff --git a/Digitization/DigiMuon/src/MuonDigiAlg.h b/Digitization/DigiMuon/src/MuonDigiAlg.h
index f5d0d412680e958cca69788dc9768121a943e45d..78a4e066f5fafe41db625ea65a91d553f197d37b 100644
--- a/Digitization/DigiMuon/src/MuonDigiAlg.h
+++ b/Digitization/DigiMuon/src/MuonDigiAlg.h
@@ -50,19 +50,32 @@ class MuonDigiAlg : public GaudiAlgorithm
   virtual StatusCode execute() ; 
   virtual StatusCode finalize() ;
   void Clear();
+  void GetSimHit(edm4hep::SimTrackerHit _simhit, dd4hep::DDSegmentation::BitFieldCoder* _m_decoder);
+  double Gethit_sipm_length_Barrel();
+  double Gethit_sipm_length_Endcap();
+  void EdeptoADC();
+  void SaveData_mapcell();
+  bool Mapcell_todata(int _message[6], std::array<unsigned long long, 2> _key);
+  void Cut3();
+  void Save_trkhit(edm4hep::TrackerHitCollection* _trkhitVec, std::array<unsigned long long, 2> _key, int _pdgid, unsigned long long _cellid, edm4hep::Vector3d _pos);
+  void Renew_strip(std::array<unsigned long long, 2> _key1, std::array<unsigned long long, 2> _key2);
+  void Find_anotherlayer(int _i, edm4hep::Vector3d _pos1, edm4hep::Vector3d _pos2, double _ddposi, int _pdgid);
+  int Get_true_pdgid(int _i, int _pdgid);
+  void Save_onelayer_signal(edm4hep::TrackerHitCollection* _trkhitVec);
+  void Save_pos(int _i);
 
 
  protected:
 
 
-  TRandom3 rand_muon;
+
 
   TTree* m_tree;
   TFile* m_wfile;
     
   SmartIF<IGeomSvc> m_geosvc;
-  dd4hep::DDSegmentation::BitFieldCoder* m_decoder1;
-  dd4hep::DDSegmentation::BitFieldCoder* m_decoder2;
+  dd4hep::DDSegmentation::BitFieldCoder* m_decoder_barrel;
+  dd4hep::DDSegmentation::BitFieldCoder* m_decoder_endcap;
   dd4hep::rec::CellIDPositionConverter* m_cellIDConverter;
   dd4hep::Detector* m_dd4hep;
 
@@ -105,14 +118,50 @@ class MuonDigiAlg : public GaudiAlgorithm
   int cell_strip[MAX_SIZE];
   int cell_fe[MAX_SIZE];
   int cell_env[MAX_SIZE];
+  int cell_superlayernumber;
+  double cell_pt;
 
 
   Gaudi::Property<int>   _writeNtuple{this,  "WriteNtuple", 1, "Write ntuple"};
   Gaudi::Property<std::string> _filename{this, "OutFileName", "testout.root", "Output file name"};
 
-  Gaudi::Property<double>  m_MuonMode{ this, "MuonMode", 0, "Control the Muon section used in Digi" };// 1->Barrel; 2->Endcap; 0->Both;
-  Gaudi::Property<double>  m_hitEff{ this, "SiPMEff", 0.95, "Efficiency of a single hit on a Strip" };
+
+  Gaudi::Property<double>  m_hitEff{ this, "SiPMEff", 1, "Efficiency of a single hit on a Strip" };
   Gaudi::Property<double>  m_EdepMin{ this, "EdepMin", 0.0001, "Minimum Edep of a mip" };
+  Gaudi::Property<double>  m_hit_Edep_min{ this, "HitEdepMin", 0.000001, "Minimum Edep of a mip"};  
+  Gaudi::Property<double>  m_hit_Edep_max{ this, "HitEdepMax", 0.1, "Maximum Edep of a mip"};  
+
+  // number of strips parallel to beam direction 
+  // in each slayer, each strip width=4cm, so 
+  int strip_length[6] = {26, 38, 50, 62, 74, 86}; //for barrel
+  std::array<unsigned long long, 2> key, key1, key2;
+  int pdgid, layer, slayer, strip, Fe, Env, anotherlayer_cell_num, true_pdgid;
+  unsigned long long cellid, abspdgid, cellid1, cellid2; 
+  double Edep, xydist, hit_sipm_length, ADC, hit_strip_length, ADCmean, Hit_max, Hit_min;
+  edm4hep::Vector3d pos, pos1, pos2;
+  edm4hep::Vector3d mcppos;
+  dd4hep::Position ddpos, ddpos1, ddpos2;  
+  int all_message1[6], all_message2[6];  // int layer1, slayer1, strip1, Fe1, Env1, pdgid1;
+  double endcap_strip_length[193] = {2.12, 2.12, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.19, 2.22,
+                                     2.24, 2.28, 2.32, 2.37, 2.45, 2.65, 2.64, 2.63, 2.62, 2.61,
+                                     2.60, 2.59, 2.57, 2.56, 2.54, 2.53, 2.51, 2.50, 2.48, 2.46, 
+                                     2.44, 2.42, 2.40, 2.38, 2.36, 2.33, 2.31, 2.28, 2.26, 2.23,
+                                     2.20, 2.17, 2.14, 2.11, 2.07, 2.04, 2.00, 1.97, 1.93, 1.89, 
+                                     1.84, 1.80, 1.75, 1.70, 1.65, 1.60, 1.54, 1.48, 1.42, 1.35, 
+                                     1.28, 1.20, 1.12, 1.02, 0.92, 0.80, 0.65, 0.46, 2.20, 2.20,
+                                     2.20, 2.20, 2.20, 2.20, 2.20, 2.21, 2.21, 2.21, 2.21, 2.22,
+                                     2.22, 2.22, 2.23, 2.23, 2.23, 2.24, 2.24, 2.25, 2.25, 2.26,
+                                     2.26, 2.27, 2.28, 2.28, 2.29, 2.30, 2.31, 2.32, 2.32, 2.33,
+                                     2.34, 2.35, 2.36, 2.38, 2.39, 2.40, 2.41, 2.43, 2.44, 2.45,
+                                     2.47, 2.49, 2.50, 2.52, 2.54, 2.56, 2.58, 2.60, 2.62, 2.65, 
+                                     2.67, 2.70, 2.73, 2.76, 2.79, 2.82, 2.86, 2.90, 2.94, 2.99,
+                                     3.04, 3.10, 3.16, 3.23, 3.31, 3.41, 3.53, 3.70, 4.14, 4.12, 
+                                     4.09, 4.06, 4.03, 4.00, 3.97, 3.94, 3.91, 3.87, 3.84, 3.81, 
+                                     3.77, 3.74, 3.70, 3.67, 3.63, 3.59, 3.55, 3.51, 3.47, 3.43, 
+                                     3.38, 3.34, 3.30, 3.25, 3.20, 3.15, 3.10, 3.05, 3.00, 2.95, 
+                                     2.89, 2.83, 2.77, 2.71, 2.65, 2.58, 2.52, 2.45, 2.37, 2.30, 
+                                     2.22, 2.14, 2.05, 1.96, 1.86, 1.76, 1.65, 1.53, 1.40, 1.25, 
+                                     1.09, 0.89, 0.63};  
 
 
   // Input collections
@@ -123,7 +172,7 @@ class MuonDigiAlg : public GaudiAlgorithm
   DataHandle<edm4hep::TrackerHitCollection>               m_outputMuonEndcap{"MuonEndcapTrackerHits", Gaudi::DataHandle::Writer, this};
 
   //DataHandle<edm4hep::MCRecoTrackerAssociationCollection> m_assMuonBarrel{"MuonBarrelTrackerHitAssociationCollection", Gaudi::DataHandle::Writer, this};
-
+  SmartIF<IRndmGenSvc> m_randSvc;
   edm4hep::TrackerHitCollection* trkhitVec;
   int m_nEvt=0;
 };