diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 6cb0a612e9d6dd229f541aa251c085d1a8181d72..e869febe27098430d8fe1f2fdce104fe429f18da 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -452,19 +452,19 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
     }
 
     if( dmrss == 2) // update time statistics for last PBCH symbol
-    {
-      // do ifft of channel estimate
-      for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
-        for (p=0; p<ue->frame_parms.nb_antenna_ports_gNB; p++) {
-          if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
-          {
-            LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset);
-            idft(idftsizeidx,
-                 (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset],
-                 (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
-          }
-        }
-    }
+      {
+	// do ifft of channel estimate
+	for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
+	  for (p=0; p<ue->frame_parms.nb_antenna_ports_gNB; p++) {
+	    if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
+	      {
+		LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset);
+		idft(idftsizeidx,
+		     (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset],
+		     (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
+	      }
+	  }
+      }
 
     //}
 
@@ -536,111 +536,111 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
     printf("dl_ch addr %p\n",dl_ch);
 #endif
     //    if ((ue->frame_parms.N_RB_DL&1)==0) {
-      // Treat first 2 pilots specially (left edge)
-      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+    // Treat first 2 pilots specially (left edge)
+    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 #ifdef DEBUG_PDCCH
-      printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
-      printf("pilot 0 : rxF - > (%d,%d) addr %p  ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
+    printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
+    printf("pilot 0 : rxF - > (%d,%d) addr %p  ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
 #endif
-      multadd_real_vector_complex_scalar(fl,
-                                         ch,
-                                         dl_ch,
-                                         16);
-      pil+=2;
-      rxF+=8;
-      //for (int i= 0; i<8; i++)
-      //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
+    multadd_real_vector_complex_scalar(fl,
+				       ch,
+				       dl_ch,
+				       16);
+    pil+=2;
+    rxF+=8;
+    //for (int i= 0; i<8; i++)
+    //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
 
-      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 #ifdef DEBUG_PDCCH
-      printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+    printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
 #endif
-      multadd_real_vector_complex_scalar(fm,
-                                         ch,
-                                         dl_ch,
-                                         16);
-      pil+=2;
-      rxF+=8;
+    multadd_real_vector_complex_scalar(fm,
+				       ch,
+				       dl_ch,
+				       16);
+    pil+=2;
+    rxF+=8;
 
-      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 
 #ifdef DEBUG_PDCCH
-      printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+    printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
 #endif
 
-      multadd_real_vector_complex_scalar(fr,
-                                         ch,
-                                         dl_ch,
-                                         16);
+    multadd_real_vector_complex_scalar(fr,
+				       ch,
+				       dl_ch,
+				       16);
                                          
 #ifdef DEBUG_PDCCH       
-      for (int m =0; m<12; m++)
-	printf("data :  dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
+    for (int m =0; m<12; m++)
+      printf("data :  dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
 #endif      
-      pil+=2;
-      rxF+=8;
-      dl_ch+=24;
-      k+=12;
+    pil+=2;
+    rxF+=8;
+    dl_ch+=24;
+    k+=12;
       
       
 
-      for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) {
+    for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) {
 
-        if (k >= ue->frame_parms.ofdm_symbol_size){
-	  k-=ue->frame_parms.ofdm_symbol_size;
-	  rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];}
+      if (k >= ue->frame_parms.ofdm_symbol_size){
+	k-=ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];}
 
-        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 #ifdef DEBUG_PDCCH
-	printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
 #endif
-        multadd_real_vector_complex_scalar(fl,
-                                           ch,
-                                           dl_ch,
-                                           16);
+      multadd_real_vector_complex_scalar(fl,
+					 ch,
+					 dl_ch,
+					 16);
 
-        //for (int i= 0; i<8; i++)
-        //            printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
+      //for (int i= 0; i<8; i++)
+      //            printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
 
-        pil+=2;
-        rxF+=8;
+      pil+=2;
+      rxF+=8;
 
-        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 #ifdef DEBUG_PDCCH
-	printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
 #endif
-        multadd_real_vector_complex_scalar(fm,
-                                           ch,
-                                           dl_ch,
-                                           16);
-        pil+=2;
-        rxF+=8;
+      multadd_real_vector_complex_scalar(fm,
+					 ch,
+					 dl_ch,
+					 16);
+      pil+=2;
+      rxF+=8;
 
-        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 
 #ifdef DEBUG_PDCCH
-	printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
 #endif
 
-        multadd_real_vector_complex_scalar(fr,
-                                           ch,
-                                           dl_ch,
-                                           16);
-        pil+=2;
-        rxF+=8;
-        dl_ch+=24;
-        k+=12;
+      multadd_real_vector_complex_scalar(fr,
+					 ch,
+					 dl_ch,
+					 16);
+      pil+=2;
+      rxF+=8;
+      dl_ch+=24;
+      k+=12;
 
-      }
+    }
 
 
-      //}
+    //}
 
   }
 
@@ -662,7 +662,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   unsigned short k;
   unsigned int pilot_cnt;
   int16_t ch_l[2],ch_r[2],ch[2],*pil,*rxF,*dl_ch;
-  int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr;
+  int16_t *fl=NULL,*fm=NULL,*fr=NULL,*fml=NULL,*fmr=NULL,*fmm=NULL,*fdcl=NULL,*fdcr=NULL,*fdclh=NULL,*fdcrh=NULL, *frl=NULL, *frr=NULL;
   int ch_offset,symbol_offset;
 
   //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
@@ -692,84 +692,84 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int8_t delta = get_delta(p, config_type);
   nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
 
-  if (config_type == pdsch_dmrs_type1){
+  if (config_type == pdsch_dmrs_type1 && ue->fd_lin_interpolation == 1){
     nushift = (p>>1)&1;
     ue->frame_parms.nushift = nushift;
     switch (delta) {
 
-      case 0://port 0,1
-        fl = filt8_l0;//left interpolation Filter for DMRS config. 1
-        fm = filt8_m0;//left middle interpolation Filter
-        fr = filt8_r0;//right interpolation Filter
-        fmm = filt8_mm0;;//middle middle interpolation Filter
-        fml = filt8_m0;//left middle interpolation Filter
-        fmr = filt8_mr0;//middle right interpolation Filter
-        fdcl = filt8_dcl0;//left DC interpolation Filter (even RB)
-        fdcr = filt8_dcr0;//right DC interpolation Filter (even RB)
-        fdclh = filt8_dcl0_h;//left DC interpolation Filter (odd RB)
-        fdcrh = filt8_dcr0_h;//right DC interpolation Filter (odd RB)
-        frl = NULL;
-        frr = NULL;
-        break;
-
-      case 1://port2,3
-        fl = filt8_l1;
-        fm = filt8_m1;
-        fr = filt8_r1;
-        fmm = filt8_mm1;
-        fml = filt8_ml1;
-        fmr = filt8_m1;
-        fdcl = filt8_dcl1;
-        fdcr = filt8_dcr1;
-        fdclh = filt8_dcl1_h;
-        fdcrh = filt8_dcr1_h;
-        frl = NULL;
-        frr = NULL;
-        break;
-
-      default:
-        msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
-        return -1;
-        break;
+    case 0://port 0,1
+      fl = filt8_l0;//left interpolation Filter for DMRS config. 1
+      fm = filt8_m0;//left middle interpolation Filter
+      fr = filt8_r0;//right interpolation Filter
+      fmm = filt8_mm0;;//middle middle interpolation Filter
+      fml = filt8_m0;//left middle interpolation Filter
+      fmr = filt8_mr0;//middle right interpolation Filter
+      fdcl = filt8_dcl0;//left DC interpolation Filter (even RB)
+      fdcr = filt8_dcr0;//right DC interpolation Filter (even RB)
+      fdclh = filt8_dcl0_h;//left DC interpolation Filter (odd RB)
+      fdcrh = filt8_dcr0_h;//right DC interpolation Filter (odd RB)
+      frl = NULL;
+      frr = NULL;
+      break;
+
+    case 1://port2,3
+      fl = filt8_l1;
+      fm = filt8_m1;
+      fr = filt8_r1;
+      fmm = filt8_mm1;
+      fml = filt8_ml1;
+      fmr = filt8_m1;
+      fdcl = filt8_dcl1;
+      fdcr = filt8_dcr1;
+      fdclh = filt8_dcl1_h;
+      fdcrh = filt8_dcr1_h;
+      frl = NULL;
+      frr = NULL;
+      break;
+
+    default:
+      LOG_E(PHY,"pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
+      return -1;
+      break;
     }
-  } else {//pdsch_dmrs_type2
+  } else if (ue->fd_lin_interpolation == 1) {//pdsch_dmrs_type2
     nushift = delta;
     ue->frame_parms.nushift = nushift;
     switch (delta) {
-      case 0://port 0,1
-        fl = filt8_l2;//left interpolation Filter should be fml
-        fr = filt8_r2;//right interpolation Filter should be fmr
-        fm = filt8_l2;
-        fmm = filt8_r2;
-        fml = filt8_ml2;
-        fmr = filt8_mr2;
-        frl = filt8_rl2;
-        frr = filt8_rm2;
-        fdcl = filt8_dcl1;
-        fdcr = filt8_dcr1;
-        fdclh = filt8_dcl1_h;
-        fdcrh = filt8_dcr1_h;
-        break;
-
-      case 2://port2,3
-        fl = filt8_l3;
-        fm = filt8_m2;
-        fr = filt8_r3;
-        fmm = filt8_mm2;
-        fml = filt8_l2;
-        fmr = filt8_r2;
-        frl = filt8_rl3;
-        frr = filt8_rr3;
-        fdcl = NULL;
-        fdcr = NULL;
-        fdclh = NULL;
-        fdcrh = NULL;
-        break;
-
-      default:
-        msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
-        return -1;
-        break;
+    case 0://port 0,1
+      fl = filt8_l2;//left interpolation Filter should be fml
+      fr = filt8_r2;//right interpolation Filter should be fmr
+      fm = filt8_l2;
+      fmm = filt8_r2;
+      fml = filt8_ml2;
+      fmr = filt8_mr2;
+      frl = filt8_rl2;
+      frr = filt8_rm2;
+      fdcl = filt8_dcl1;
+      fdcr = filt8_dcr1;
+      fdclh = filt8_dcl1_h;
+      fdcrh = filt8_dcr1_h;
+      break;
+
+    case 2://port2,3
+      fl = filt8_l3;
+      fm = filt8_m2;
+      fr = filt8_r3;
+      fmm = filt8_mm2;
+      fml = filt8_l2;
+      fmr = filt8_r2;
+      frl = filt8_rl3;
+      frr = filt8_rr3;
+      fdcl = NULL;
+      fdcr = NULL;
+      fdclh = NULL;
+      fdcrh = NULL;
+      break;
+
+    default:
+      LOG_E(PHY,"pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
+      return -1;
+      break;
     }
   }
 
@@ -791,8 +791,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
     printf("rxF addr %p p %d\n", rxF,p);
     printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
 #endif
-
-    if (config_type == pdsch_dmrs_type1) {
+    
+    if (config_type == pdsch_dmrs_type1 && ue->fd_lin_interpolation == 1) {
 
       // Treat first 2 pilots specially (left edge)
       ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -846,8 +846,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
 
       for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pdsch-3); pilot_cnt+=2) {
     	//if ((pilot_cnt%6)==0)
-    		//dl_ch+=4;
-		//printf("re_offset %d\n",re_offset);
+	//dl_ch+=4;
+	//printf("re_offset %d\n",re_offset);
 
         ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
         ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -883,7 +883,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
       ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
       ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 #ifdef DEBUG_PDSCH
-	printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
 #endif
       multadd_real_vector_complex_scalar(fm,
                                          ch,
@@ -923,59 +923,59 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                          dl_ch,
                                          8);
     
-    // check if PRB crosses DC and improve estimates around DC
-    if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) {
-      dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
-      uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
-      uint16_t idxPil = idxDC/2;
-      re_offset = k;
-      pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
-      pil += (idxPil-2);
-      dl_ch += (idxDC-4);
-      dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10);
-      re_offset = (re_offset+idxDC/2-2) % ue->frame_parms.ofdm_symbol_size;
-      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
-      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+      // check if PRB crosses DC and improve estimates around DC
+      if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) {
+	dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
+	uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
+	uint16_t idxPil = idxDC/2;
+	re_offset = k;
+	pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)];
+	pil += (idxPil-2);
+	dl_ch += (idxDC-4);
+	dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10);
+	re_offset = (re_offset+idxDC/2-2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+	ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
       
-      // for proper allignment of SIMD vectors
-      if((ue->frame_parms.N_RB_DL&1)==0) {
+	// for proper allignment of SIMD vectors
+	if((ue->frame_parms.N_RB_DL&1)==0) {
         
-        multadd_real_vector_complex_scalar(fdcl,
-                                           ch,
-                                           dl_ch-4,
-                                           8);
+	  multadd_real_vector_complex_scalar(fdcl,
+					     ch,
+					     dl_ch-4,
+					     8);
         
-        pil += 4;
-        re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
-        rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
-        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+	  pil += 4;
+	  re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
+	  rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+	  ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	  ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
         
-        multadd_real_vector_complex_scalar(fdcr,
-                                           ch,
-                                           dl_ch-4,
-                                           8);
-      } else {
-
-        multadd_real_vector_complex_scalar(fdclh,
-                                           ch,
-                                           dl_ch,
-                                           8);
+	  multadd_real_vector_complex_scalar(fdcr,
+					     ch,
+					     dl_ch-4,
+					     8);
+	} else {
+
+	  multadd_real_vector_complex_scalar(fdclh,
+					     ch,
+					     dl_ch,
+					     8);
         
-        pil += 4;
-        re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
-        rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
-        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
-        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+	  pil += 4;
+	  re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
+	  rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+	  ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	  ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
         
-        multadd_real_vector_complex_scalar(fdcrh,
-                                           ch,
-                                           dl_ch,
-                                           8);
+	  multadd_real_vector_complex_scalar(fdcrh,
+					     ch,
+					     dl_ch,
+					     8);
+	}
       }
-    }
-    } else { //pdsch_dmrs_type2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
+    } else if (config_type==pdsch_dmrs_type2 && ue->fd_lin_interpolation == 1){ //pdsch_dmrs_type2  |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0|
 
       // Treat first 4 pilots specially (left edge)
       ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -1187,7 +1187,96 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
         }
       }
     }
-
+    else if (config_type==pdsch_dmrs_type1) { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 6 DMRS REs and use a common value for the whole PRB
+      
+      for (pilot_cnt=0; pilot_cnt<6*nb_rb_pdsch; pilot_cnt+=6) {
+	ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+	ch[0]/=6;
+	ch[1]/=6;
+	((__m128i*)dl_ch)[0]=_mm_set1_epi32(*(int32_t*)ch);
+	((__m128i*)dl_ch)[1]=((__m128i*)dl_ch)[0];
+	((__m128i*)dl_ch)[2]=((__m128i*)dl_ch)[0];
+	dl_ch+=24;
+      }
+    }
+    else  { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB
+      for (pilot_cnt=0; pilot_cnt<4*nb_rb_pdsch; pilot_cnt+=4) {
+	ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+
+	ch[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+	ch[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+
+	pil+=2;
+	re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size;
+	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+	ch[0]>>=2;
+	ch[1]>>=2;
+	((__m128i*)dl_ch)[0]=_mm_set1_epi32(*(int32_t*)ch);
+	((__m128i*)dl_ch)[1]=((__m128i*)dl_ch)[0];
+	((__m128i*)dl_ch)[2]=((__m128i*)dl_ch)[0];
+	dl_ch+=24;
+      }
+    }
 #ifdef DEBUG_PDSCH
     dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset];
     for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pdsch*12/8); idxP++) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 9a312572446043504821cd77c152541d29e77f39..34d32e5f9cd9930861e2522db6c65a02a7b4806e 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -474,7 +474,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
           for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
             avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
 
-        pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3;
+        pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+1;
      }
      else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM)
      {
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 390574a66b049c19648fc8ca6cf6573265467ba1..bcc24610ff9c281b1caed31bdaac7d595e34efa2 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -852,6 +852,9 @@ typedef struct {
 
   uint32_t high_speed_flag;
   uint32_t perfect_ce;
+  // flag to activate linear interpolation in frequency-domain channel estimation
+  // when off (default), this just averages channel on per-PRB basis
+  uint32_t fd_lin_interpolation;
   int16_t ch_est_alpha;
   int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX];
 
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 9581038283f993ce18d738ed7f84d1eef344c9f6..6860dd5c6bf2f86c09df6163e4a6a29f4963bc3d 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -1168,7 +1168,7 @@ int main(int argc, char **argv)
       LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1);
       if (UE->frame_parms.nb_antennas_rx>1)
 	LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1);
-      LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1);
+      LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0][0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1);
       write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
       LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0);
       break;