/*
 * Filter for general low complexity using dust
 */
static void finish_filter_dust(finish_t *fin, char *seq, int seqlen) {
    int i;

    if (fin->opts.debug[FIN_DEBUG_DUST])
	puts("Filtering using dust...");

    /* Filter using Dust */
    set_dust_level(fin->opts.dust_level);
    dust(seqlen, seq);

    /* Look for low complexity data within 32 bases of the end,
     * if so extend to ends
     */
    for (i = 0; i < seqlen && i < 32; i++) {
	if (seq[i] == '#') {
	    for (i = 0; i < 32 && i < seqlen; i++)
		seq[i] = '#';
	    break;
	}
    }

    for (i = 0; seqlen-1-i >= 0 && i < 32; i++) {
	if (seq[seqlen-1-i] == '#') {
	    for (i = 0; seqlen-1-i >= 0 && i < 32; i++)
		seq[seqlen-1-i] = '#';
	    break;
	}
    }
    /*
   if (fin->opts.debug[FIN_DEBUG_DUST] > 1)
	printf("%.*s\n", seqlen, seq);
    */
}
Exemple #2
0
/*---------------------------------------------------------------
  spec_pairs "ст", "сл" и др.
----------------------------------------------------------------*/
static void spec_pairs()
{
  struct cut_elm *cut;
  int16_t i,ip; //текущее и предыдущее сечения
  SVERS *vers;                   //текущая версия
  uchar let,letp;                 //текущая и предыдущая буквы
  struct cut_elm *cuts;
  int16_t is,x0;  //правая граница "с"
  int16_t m_row;                     //средняя базовая линия

  det_snap(LC, "special pairs");

  i=ncut-1;
  letp=0;
  ip=i;
  while (i>0)
    {
     cut=cut_list+i;
	 vers=&cut->versm;
	 let=vers->vers[0].let;
     if (dust(vers))
       {
        cuts=cut_list+cut->px;  //левый край dust'а
        if (cuts->dh != 0 &&      //dust отрезан слева
            addij(LC,r,cut_list,vers_list,ncut,cuts->px,i,0)==0 &&
            cut->versm.vers[0].prob > cuts->versm.vers[0].prob
           ) ;                     //приклеили
          else
            if (cut->dh != 0)       //dust отрезан справа
              addij(LC,r,cut_list,vers_list,ncut,i,ip,0);
       }
      else
        if ( cut->dh != 0 && strchr("кКтТуУ",let) &&
		    !is_russian_baltic_conflict(let) && // 17.07.2001 E.P.
			!is_russian_turkish_conflict(let)&&	// 21.05.2002 E.P.
		     (letp==(uchar)'г' || letp==(uchar)'Г')
		   )
          {
           int16_t  j,il=cut->px;
           int16_t x0=cut->x-((cut_list[ip].x-cut->x)>>1);
           uchar *letr=&cut_list[ip].versm.vers[0].let;
           for (j=i-1,cuts=cut-1; j>il && cuts->x >= x0; j--,cuts--)
             {
              if (addij(LC,r,cut_list,vers_list,ncut,il,j,0)>1)
				 break;
//              if (cut_list[j].versm.vers[0].prob<trs2)
//			       break;
              if (addij(LC,r,cut_list,vers_list,ncut,j,ip,0)>1)
				 continue;
              if ( (*letr==(uchar)'т' || *letr==(uchar)'Т')  &&
					!is_russian_baltic_conflict(*letr) && // 17.07.2001 E.P.
					!is_russian_turkish_conflict(*letr)	// 21.05.2002 E.P.
				 )
				 break;
             }
          }
         else
            {
             if (cut->dh != 0 &&
Exemple #3
0
/*
  To compute the optical scattering parameters (extinction and scattering
  coefficients, single scattering albedo, phase function, assymetry factor) at the ten discrete
  wavelengths for the selected model (or created model) from:
  (1) the characteristics of the basic components of the International Radiation Commission.
  (1983).
  dust-like component (D.L., SUBROUTINE DUST)
  oceanic component (O.C., SUBROUTINE OCEA)
  water-soluble component (W.S., SUBROUTINE WATE)
  soot component (S.O., SUBROUTINE SOOT)
  (2) pre-computed caracteristics,
  now available are the desertic aerosol model corresponding to background conditions, as
  described in Shettle(1984), a stratospheric aerosol model as measured Mona Loa (Hawaii)
  during El Chichon eruption and as described by King et al. (1984), and a biomass burning
  aerosol model as deduced from measurements taken by sunphotometers in Amazonia.
  (SUBROUTINES BDM, STM and BBM)
  (3) computed using the MIE theory with inputs (size distribution, refractive indexes...) given
  by the user (see SUBROUTINES MIE and EXSCPHASE).
  These models don't correspond to a mixture of the four basic components.
*/
void AerosolModel::aeroso(const float xmud)
{
    /* sra basic components for aerosol model, extinction coefficients are */
    /* in km-1. */
    /*     dust-like = 1 */
    /*     water-soluble = 2 */
    /*     oceanique = 3 */
    /*     soot = 4 */
    static const double vi[4] = { 113.983516, 1.13983516e-4, 5.1444150196, 5.977353425e-5 };
    static const double ni[4] = { 54.734, 1868550., 276.05, 1805820. };

    /* i: 1=dust-like 2=water-soluble 3=oceanic 4=soot */
    static const float s_ex[4][10] =
    {
        {   0.1796674e-01,0.1815135e-01,0.1820247e-01,0.1827016e-01,0.1842182e-01,
            0.1853081e-01,0.1881427e-01,0.1974608e-01,0.1910712e-01,0.1876025e-01
        },
        {   0.7653460e-06,0.6158538e-06,0.5793444e-06,0.5351736e-06,0.4480091e-06,
            0.3971033e-06,0.2900993e-06,0.1161433e-06,0.3975192e-07,0.1338443e-07
        },
        {   0.3499458e-02,0.3574996e-02,0.3596592e-02,0.3622467e-02,0.3676341e-02,
            0.3708866e-02,0.3770822e-02,0.3692255e-02,0.3267943e-02,0.2801670e-02
        },
        {   0.8609083e-06,0.6590103e-06,0.6145787e-06,0.5537643e-06,0.4503008e-06,
            0.3966041e-06,0.2965532e-06,0.1493927e-06,0.1017134e-06,0.6065031e-07
        }
    };

    static const float s_sc[4][10] =
    {
        {   0.1126647e-01,0.1168918e-01,0.1180978e-01,0.1196792e-01,0.1232056e-01,
            0.1256952e-01,0.1319347e-01,0.1520712e-01,0.1531952e-01,0.1546761e-01
        },
        {   0.7377123e-06,0.5939413e-06,0.5587120e-06,0.5125148e-06,0.4289210e-06,
            0.3772760e-06,0.2648252e-06,0.9331806e-07,0.3345499e-07,0.1201109e-07
        },
        {   0.3499455e-02,0.3574993e-02,0.3596591e-02,0.3622465e-02,0.3676338e-02,
            0.3708858e-02,0.3770696e-02,0.3677038e-02,0.3233194e-02,0.2728013e-02
        },
        {   0.2299196e-06,0.1519321e-06,0.1350890e-06,0.1155423e-06,0.8200095e-07,
            0.6469735e-07,0.3610638e-07,0.6227224e-08,0.1779378e-08,0.3050002e-09
        }
    };

    static const float ex2[10] =
    {
        43.83631f, 42.12415f, 41.57425f, 40.85399f, 39.1404f,
        37.89763f, 34.67506f, 24.59f, 17.96726f, 10.57569f
    };

    static const float sc2[10] =
    {
        40.28625f, 39.04473f, 38.6147f, 38.03645f, 36.61054f,
        35.54456f, 32.69951f, 23.41019f, 17.15375f,10.09731f
    };

    static const float ex3[10] =
    {
        95397.86f, 75303.6f, 70210.64f, 64218.28f, 52430.56f,
        45577.68f, 31937.77f, 9637.68f, 3610.691f, 810.5614f
    };

    static const float sc3[10] =
    {
        92977.9f, 73397.17f, 68425.49f,	62571.8f, 51049.87f,
        44348.77f, 31006.21f, 9202.678f, 3344.476f,	664.1915f
    };

    static const float ex4[10] =
    {
        54273040.f, 61981440.f, 63024320.f, 63489470.f, 61467600.f,
        58179720.f, 46689090.f, 15190620.f, 5133055.f, 899859.4f
    };


    static const float sc4[10] =
    {
        54273040.f, 61981440.f, 63024320.f, 63489470.f, 61467600.f,
        58179720.f, 46689090.f, 15190620.f, 5133055.f, 899859.4f
    };

    static const float s_asy[4][10] =
    {
        {0.896,0.885,0.880,0.877,0.867,0.860,0.845,0.836,0.905,0.871},
        {0.642,0.633,0.631,0.628,0.621,0.616,0.610,0.572,0.562,0.495},
        {0.795,0.790,0.788,0.781,0.783,0.782,0.778,0.783,0.797,0.750},
        {0.397,0.359,0.348,0.337,0.311,0.294,0.253,0.154,0.103,0.055}
    };

    static const float asy2[10] = { .718f, .712f, .71f, .708f, .704f, .702f, .696f, .68f, .668f, .649f };

    static const float asy3[10] = { .704f, .69f, .686f, .68f, .667f, .659f, .637f, .541f, .437f, .241f };
    static const float asy4[10] = { .705f, .744f, .751f, .757f, .762f, .759f, .737f, .586f, .372f, .139f };

    /* local */
    double coef;
    float sigm;
    double sumni;
    double dd[4][10];
    double pha[5][10][83];

    float ex[4][10];
    float sc[4][10];
    float asy[4][10];

    int i;	/* crappy VS6 */
    /* initialize ex, sc & asy */
    for(i = 0; i < 4; i++)
    {
        int j;
        for(j = 0; j < 10; j++) ex[i][j] = s_ex[i][j];
        for(j = 0; j < 10; j++) sc[i][j] = s_sc[i][j];
        for(j = 0; j < 10; j++) asy[i][j] = s_asy[i][j];
    }

    /* optical properties of aerosol model computed from sra basic comp */
    for (i = 0; i < 10; ++i)
    {
        if(i == 4 && iaer == 0) sixs_aer.ext[i] = 1.f;
        else sixs_aer.ext[i] = 0.f;
        sca[i] = 0.f;
        sixs_aer.ome[i] = 0.f;
        sixs_aer.gasym[i] = 0.f;
        sixs_aer.phase[i] = 0.f;

        for (int k = 1; k <= 83; ++k) sixs_sos.phasel[i][k] = 0.f;
    }

    /* return if iear = 0 */
    if(iaer == 0) return;

    /* look for an interval in cgaus */
    long int j1 = -1;
    for (i = 0; i < 82; ++i)
        if (xmud >= sixs_sos.cgaus[i] && xmud < sixs_sos.cgaus[i+1])  {
            j1 = i;
            break;
        }
    if(j1 == -1) return; /* unable to find interval */

    coef = -(xmud - sixs_sos.cgaus[j1]) / (sixs_sos.cgaus[j1+1] - sixs_sos.cgaus[j1]);

    switch(iaer)
    {
    case 12: /* read from file */
    {
        load();
        for(i = 0; i < 10; i++)
            sixs_aer.phase[i] = (float)(sixs_sos.phasel[i][j1] +
                                        coef*(sixs_sos.phasel[i][j1]-sixs_sos.phasel[i][j1+1]));
        return;
    }
    case 5:
    {
        for(i = 0; i < 10; i++)
        {
            asy[0][i]	= asy2[i];
            ex[0][i]	= ex2[i];
            sc[0][i]	= sc2[i];
        }
        break;
    }
    case 6:
    {
        for(i = 0; i < 10; i++)
        {
            asy[0][i]	= asy3[i];
            ex[0][i]	= ex3[i];
            sc[0][i]	= sc3[i];
        }
        break;
    }
    case 7:
    {
        for(i = 0; i < 10; i++)
        {
            asy[0][i]	= asy4[i];
            ex[0][i]	= ex4[i];
            sc[0][i]	= sc4[i];
        }
        break;
    }
    default:
        ;
    }


    if(iaer >= 5 && iaer <= 11)
    {
        /* calling a special aerosol model */

        switch(iaer)
        {
        /* (background desert model...) */
        case 5:
            bdm();
            break;
        /* (biomass burning model...) */
        case 6:
            bbm();
            break;
        /* (stratospherique aerosol model...) */
        case 7:
            stm();
            break;

        /* (user defined model from size distribution) */
        case 8:
        case 9:
        case 10:
        case 11:
            mie (ex, sc, asy);
            break;
        }

        for (int i = 0; i < 10; i++)
        {
            dd[0][i] = (*sixs_aerbas.ph)[i][j1] + coef * ((*sixs_aerbas.ph)[i][j1] - (*sixs_aerbas.ph)[i][j1+1]);
            for(int k = 0; k < 83; k++) pha[0][i][k] = (*sixs_aerbas.ph)[i][k];
        }

        mie_in.icp = 1;
        mie_in.cij[0] = 1.f;
        /* for normalization of the extinction coefficient */
        nis = 1. / ex[0][3];
    }
    else {
        /* calling each sra components */
        mie_in.icp = 4;
        /*  -dust */
        dust();
        for(i = 0; i < 10; i++)
        {
            dd[0][i] = (*sixs_aerbas.ph)[i][j1] + coef * ((*sixs_aerbas.ph)[i][j1] - (*sixs_aerbas.ph)[i][j1+1]);
            for(int k = 0; k < 83; k++) pha[0][i][k] = ((*sixs_aerbas.ph))[i][k];
        }

        /* -water soluble */
        wate();
        for(i = 0; i < 10; i++)
        {
            dd[1][i] = (*sixs_aerbas.ph)[i][j1]+coef*((*sixs_aerbas.ph)[i][j1]-(*sixs_aerbas.ph)[i][j1+1]);
            for(int k = 0; k < 83; k++) pha[1][i][k] = (*sixs_aerbas.ph)[i][k];
        }


        /* -oceanic type */
        ocea();
        for(i = 0; i < 10; i++)
        {
            dd[2][i] = (*sixs_aerbas.ph)[i][j1]+coef*((*sixs_aerbas.ph)[i][j1]-(*sixs_aerbas.ph)[i][j1+1]);
            for(int k = 0; k < 83; k++) pha[2][i][k] = (*sixs_aerbas.ph)[i][k];
        }

        /* -soot */
        soot();
        for(i = 0; i < 10; i++)
        {
            dd[3][i] = (*sixs_aerbas.ph)[i][j1]+coef*((*sixs_aerbas.ph)[i][j1]-(*sixs_aerbas.ph)[i][j1+1]);
            for(int k = 0; k < 83; k++) pha[3][i][k] = (*sixs_aerbas.ph)[i][k];
        }

        /* summ of the c/vi calculation */
        sumni = 0.f;
        sigm = 0.f;

        for(i = 0; i < 4; i++) sigm+=(float)(c[i]/vi[i]);

        /* cij coefficients calculation */
        for(i = 0; i < 4; i++) {
            mie_in.cij[i] = (float)(c[i]/vi[i]/sigm);
            sumni += mie_in.cij[i]/ni[i];
        }

        nis = 1. / sumni;
    }


    /*     mixing parameters calculation */
    for(i = 0; i < 10; i++)
    {
        for(int j = 0; j < mie_in.icp; j++)
        {
            sixs_aer.ext[i] +=		(float)(ex[j][i] * mie_in.cij[j]);
            sca[i] +=				(float)(sc[j][i] * mie_in.cij[j]);
            sixs_aer.gasym[i] +=	(float)(sc[j][i] * mie_in.cij[j] * asy[j][i]);
            sixs_aer.phase[i] +=	(float)(sc[j][i] * mie_in.cij[j] * dd[j][i]);

            for(int k = 0; k < 83; k++)
                sixs_sos.phasel[i][k] += (float)(sc[j][i] * mie_in.cij[j] * pha[j][i][k]);
        }

        sixs_aer.ome[i] = sca[i]/sixs_aer.ext[i];
        sixs_aer.gasym[i] /= sca[i];
        sixs_aer.phase[i] /= sca[i];

        for(int k = 0; k < 83; k++)	sixs_sos.phasel[i][k] /= sca[i];

        sixs_aer.ext[i] *= (float)nis;
        sca[i] *= (float)nis;
    }

    if (filename.size() != 0 && iaer >= 8 && iaer <= 11) save();
}
Exemple #4
0
/*------------------------------------------------------------------
  dp_pass0  линейный проход в растре r на множестве ncut
            точек cut_list; vers_list - результаты для отдельных
            сегментов; LC - cell слева от растра
------------------------------------------------------------------*/
void dp_pass0(cell *CP, raster *rp, struct cut_elm *cutp,
              seg_vers **versp, int16_t n)
{
  int16_t i,j,x;
  int16_t i1,i2;
  uchar let;
  int16_t cc;
  struct cut_elm *cut;
  SVERS *vers;
  int16_t pass;
//  seg_vers *cur_vers;

  if ((ncut=n)<2)  return;
  LC=CP; r=rp; cut_list=cutp; vers_list=versp;
  iemax=ncut-1;  right_dust=0;  fl_b=0;  connect_=1;
  ie1=iemax;  vers=&cut_list[ie1].versm;
  ie2=ir=(let(vers) || dust(vers)) ? ie1-1 : ie1;
  ib1=ib2=0;      vers=&cut_list[1].versm;
  if (let(vers))  ib2=1;
  else
    if (cut_list->gvarm & c_cg_cutdone)  ib2=on_path(0,ie2,cut_list);
  iec=ib2;  ibc=ie2;
  w1=sym_width-(sym_width>>2);  w2=sym_width+(sym_width>>2);  h2=r->h<<1;
  cut=cut_list+ie1;
/*
//отщепляем правые dust'ы
  if (dust(&cut->versm) && cut->duflm==0)
  {
    right_dust=1;  iemax--;  cut--;
//    if (dust(&cut->versm) && cut->duflm==0)  iemax--;
    ir=ie1=ie2=iemax;
  }
*/
//крайние хорошие распознаем с сопутствующими dust'ами
  if (ie1 != ie2 && cut->duflm)
    addij(LC,r,cut_list,vers_list,ncut,ie2,ie1,0);
  if (ib1 != ib2)
  {
    cut=cut_list+ib2;
    if (cut->duflm)
		addij(LC,r,cut_list,vers_list,ncut,ib1,ib2,0);
    if ((let=cut->versm.vers[0].let)==(uchar)'ь' &&
			!is_russian_baltic_conflict(let) ||		// 17.07.2001 E.P.
			let==(uchar)'Ь'
	   )
      fl_b=1;
  }

  if (ib2>=ie2)
  {
    addij(LC,r,cut_list,vers_list,ncut,ib1,ie1,0);
    goto test_right_dust;
  }

  do
  {
    if (!fl_b && iec != iemax)
    {
#ifndef MY_DEBUG
    if (det_trace)
#endif
      cg_show_rast(LC,r,"left to right",cut_list); //растр - на экран

      cc=l2r(&ib1,&ib2,&il);
      if (cc)  goto finish;

      if (il<iemax && iec>il &&
          (cut=cut_list+il)->dh==0 &&
          (x=cut->x-cut_list->x) < h2 && x > sym_width>>1 &&
          cut->versm.vers[0].prob>=190 &&
          !not_connect_sect(0,il,cut_list))
      {                 //оставим, как есть, и попробуем дальше
        i1=i2=il;
        cc=l2r(&i1,&i2,&i);
        if (cc)         //дальше - хорошо, вернемся к подозрительному участку
        {
  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"right side reached, return %d-%d",0,il);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
          ib1=i1;  ib2=i2;  i1=i2=il;  il=i;
          cc=r2l(&i,&i2,&i1,0);
          goto finish;
        }
      }
    }
    if (ibc != 0 && abs(cut_list[ie2].x-cut_list[ib2].x)>minw)
    {
    //слева не вышло, пробуем справа налево

  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"left: reliable=%d advance=%d; try right",ib2,il);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }

      cc=r2l(&ir,&ie2,&ie1,2);
      if (cc)  goto finish;

      if (ir>0 && ibc<ir &&
          (cut=cut_list+ir)->dh==0 &&
          (x=cut_list[iemax].x-cut->x) < h2 && x > sym_width>>1 &&
          cut_list[iemax].versm.vers[0].prob>=190 &&
          !not_connect_sect(ir,iemax,cut_list))
      {                 //оставим, как есть, и попробуем дальше
        i1=i2=ie2;
        cc=r2l(&i,&i2,&i1,2);
        if (cc)         //дальше - хорошо, вернемся к подозрительному участку
        {
  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"left side reached, return %d-%d",ir,iemax);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
          ie1=i1;  ie2=i2;  i1=i2=ir;  ir=i;
          cc=l2r(&i1,&i2,&i);
          goto finish;
        }
      }
    }
    if (abs(cut_list[ie2].x-cut_list[ib2].x)<=minw)
    {
      j=on_path(ie2,iemax,cut_list);
      if (j==0)  break;
      if (ib2==0)  addij(LC,r,cut_list,vers_list,ncut,0,j,0);
      else         one_cut(cut_list[ib2].px,ib2,ie2,j);
      goto test_right_dust;
    }

    if (il==ie2 && (iec>il || iec==iemax) &&
        ir==ib2 && (ibc<ir || ibc==0)     &&
        cut_list[ie2].versm.vers[0].prob>MINlet)
      goto finish;
    if (il==ie2 && (iec>il || iec==iemax) || ir==ib2 && (ibc<ir || ibc==0))
      if (cut_list[ie2].versm.vers[0].prob>=190)  goto finish;
    if (il==ir)
    {
      version *vers0;
      char *ilet;
      if (connect_ && cut_list[il].dh==0)
      {
        addij(LC,r,cut_list,vers_list,ncut,ib2,ie2,0);
        if (cut_list[ie2].versm.vers[0].prob>trs2)  goto finish;
      }
      if (ir != ie2 && cut_list[ie2].x-cut_list[ir].x > w2)
      {
        i1=i2=ir;
        if ( l2r(&i1,&i2,&i) || i>0 && on_path(i,iemax,cut_list) &&
             cut_list[i].versm.vers[0].prob>=190)
        {
          j=on_path(ir,iemax,cut_list);
          vers0=&cut_list[j].versm.vers[0];
          if ( (let=vers0->let)==(uchar)'т' &&
			  !is_russian_baltic_conflict(let) && 	// 17.07.2001 E.P.
			  !is_russian_turkish_conflict(let) 	// 21.05.2002 E.P.
			  )
            ie1=j;
          else
            if ( (ilet=strchr(letters_right_to_bad,let))!=0 &&
			    !is_russian_baltic_conflict(let) // 17.07.2001 E.P.
			   )
              if (vers0->prob < prob_right_to_bad[(uchar*)ilet-letters_right_to_bad])
                ie1=j;          //может быть частью буквы
          ie2=ir;
        }
      }
      if (il != ib2 && cut_list[il].x-cut_list[ib2].x > w2)
      {
        i2=il;  i1 = (ie2==il) ? ie1 : i2;
        if (r2l(&i,&i2,&i1,0) || on_path(i,ib2,cut_list) &&
            cut_list[i2].versm.vers[0].prob>=190)
        {
          cut=cut_list+il;
          vers0=&cut->versm.vers[0];
          if ((let=vers0->let)==(uchar)'т' &&
			  !is_russian_baltic_conflict(let) && 	// 17.07.2001 E.P.
			  !is_russian_turkish_conflict(let) 	// 21.05.2002 E.P.
			  )
            ib1=cut->px;
          else
            if ( (ilet=strchr(letters_right_to_bad,let)) !=0 &&
			    !is_russian_baltic_conflict(let) // 17.07.2001 E.P.
			   )
              if (vers0->prob < prob_right_to_bad[(uchar*)ilet-letters_right_to_bad])
                ie1=cut->px;          //может быть частью буквы
          ib2=il;
        }
      }
      if (ib2==ie2)  goto finish;
    }
//    if (il>ir)  break;
//    if (iec==iemax || ibc==0 || iec<ibc)  break;
    if (iec==iemax && ibc==0)  break;
    connect_ = 1-connect_;
  }
  while (!connect_);

  if (right_dust)
    if (glue_right_dust())
    {
      spec_pairs();  return;
    }

  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"right: reliable=%d advance=%d; ",ie2,ir);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }

  //не сошлись, запускаем ДП между ними

  if (ie1-ib1 <= 2)
    if (!good_path(cut_list,ncut))  { ib1=ib2=0; ie2=ie1=ncut-1; }

DP:
  if (ie1-ib1 <= 2)
  {
    spec_pairs();  return;
  }

  il=ib1; ir=ie1;

  for (pass=1; pass<=4; pass++)
  {
    dp_bound(cut_list,vers_list,pass,&il,&ir);
    if (ir<=il)
    {
      if (ib1 != 0 || ie1 != ncut-1)  spec_pairs();   //неполное ДП
      return;
    }
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"try DP %d-%d pass=%d",il,ir,pass);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
    for ( i=il+1; i<=ir; i++ )
    {
      if ( !ben_cut(cut_list+i) )  //разрешен на данном проходе
      {
        snap_newpoint(i);
        for (j=i-1; j>=il; j--)
          if ( !ben_cut(cut_list+j) )
            if (addij(LC,r,cut_list,vers_list,ncut,j,i,0) & 8)  break                                                               ;
      }                                                     //8-широк                                                               ий
    }
  }  //pass

  if (ib1==0 && ie1==ncut-1)  return;   //полное ДП - больше нечего делать

  if (good_path(cut_list,ncut))  { spec_pairs();  return; }

//ДП по всему участку

  il=0;  ir=ncut-1;
  for (pass=1; pass<=4; pass++)
  {
    dp_bound(cut_list,vers_list,pass,&il,&ir);
    if (ir<=il)  return;
    if (il>=ib1 && ir<=ie1)  return; //на этом интервале уже считали
/*
    {
      struct cut_elm *cute=cut_list+ir;
      for (cut=cut_list+(il+1); cut<cute; cut++)
        if ((cut->var & 0x7F)==40)  break;
      if (cut==cute)  return;  //новых точек не будет
    }
*/
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"try DP %d-%d pass=%d",il,ir,pass);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
    for ( i=il+1; i<=ir; i++ )
    {
      if ( !ben_cut(cut_list+i) )  //разрешен на данном проходе
      {
        snap_newpoint(i);
        for (j=i-1; j>=il; j--)
          if ( !ben_cut(cut_list+j) )
            if (addij(LC,r,cut_list,vers_list,ncut,j,i,0) & 8)  break                                                               ;
      }                                                     //8-широк                                                               ий
    }
  }  //pass
  return;

test_right_dust:
  if (right_dust)  glue_right_dust();
  if (!good_path(cut_list,ncut))  { ib1=ib2=0; ie2=ie1=ncut-1; goto DP; }
  spec_pairs();
  return;

finish:
  if (right_dust)  glue_right_dust();
  spec_pairs();
  return;
}