StructureAdapterPtr
createStructureAdapter(const ObjCryst::Crystal& cryst)
{
    const double radtodeg = 180 / M_PI;
    CrystalStructureAdapterPtr adpt(new CrystalStructureAdapter);
    adpt->setLatPar(
            cryst.GetLatticePar(0),
            cryst.GetLatticePar(1),
            cryst.GetLatticePar(2),
            radtodeg * cryst.GetLatticePar(3),
            radtodeg * cryst.GetLatticePar(4),
            radtodeg * cryst.GetLatticePar(5));
    // find out number of scatterers in the asymmetric unit
    const ObjCryst::ScatteringComponentList& scl =
        cryst.GetScatteringComponentList();
    size_t nbComponent = scl.GetNbComponent();
    adpt->reserve(nbComponent);
    Atom ai;
    const Lattice& L = adpt->getLattice();
    for (size_t i = 0; i < nbComponent; ++i)
    {
        const ObjCryst::ScatteringComponent& sc = scl(i);
        const ObjCryst::ScatteringPower* sp = sc.mpScattPow;
        // Skip over this if it is a dummy atom. A dummy atom has no
        // mpScattPow, and therefore no type. It's just in a structure as a
        // reference position.
        if (sp == NULL) continue;
        ai.occupancy = sc.mOccupancy;
        ai.anisotropy = !(sp->IsIsotropic());
        ai.atomtype = sp->GetSymbol();
        R3::Vector xyz(sc.mX, sc.mY, sc.mZ);
        ai.xyz_cartn = L.cartesian(xyz);
        // Store Uij
        R3::Matrix uijl = getUij(sp);
        ai.uij_cartn = ai.anisotropy ?  L.cartesianMatrix(uijl) : uijl;
        adpt->append(ai);
    }
    const ObjCryst::SpaceGroup& spacegroup = cryst.GetSpaceGroup();
    CrystalStructureAdapter::SymOpVector symops =
        fetchSymmetryOperations(spacegroup);
    CrystalStructureAdapter::SymOpVector::const_iterator op;
    for (op = symops.begin(); op != symops.end(); ++op)  adpt->addSymOp(*op);
    adpt->updateSymmetryPositions();
    return adpt;
}
StructureAdapterPtr
createStructureAdapter(const ObjCryst::Molecule& molecule)
{
    AtomicStructureAdapterPtr adpt(new AtomicStructureAdapter);
    size_t nbComponent = molecule.GetNbComponent();
    adpt->reserve(nbComponent);
    Atom ai;
    for (size_t i = 0; i < nbComponent; ++i)
    {
        const ObjCryst::MolAtom& atom = molecule.GetAtom(i);
        if (atom.IsDummy()) continue;
        ai.occupancy = atom.GetOccupancy();
        const ObjCryst::ScatteringPower* sp = &(atom.GetScatteringPower());
        ai.anisotropy = !(sp->IsIsotropic());
        ai.atomtype = sp->GetSymbol();
        ai.xyz_cartn[0] = atom.X();
        ai.xyz_cartn[1] = atom.Y();
        ai.xyz_cartn[2] = atom.Z();
        // Store Uij
        ai.uij_cartn = getUij(sp);
        adpt->append(ai);
    }
    return adpt;
}
예제 #3
0
void vpTemplateTracker::computeOptimalBrentGain(const vpImage<unsigned char> &I,vpColVector &tp,double tMI,vpColVector &direction,double &alpha)
{
  vpColVector **ptp;
  ptp=new vpColVector*[4];
  vpColVector p0(nbParam);
  p0=tp;

  //valeur necessaire si conditionnel
  vpColVector dpt(Warp->getNbParam());
  vpColVector adpt(Warp->getNbParam());

  vpColVector p1(nbParam);
  if(useCompositionnal)
  {
    if(useInverse)
      Warp->getParamInverse(direction,dpt);
    else
      dpt=direction;
    Warp->pRondp(tp,dpt,p1);
  }
  else
  {
    p1=tp+direction;
  }

  vpColVector p2(nbParam);
  if(useCompositionnal)
  {
    adpt=alpha*direction;
    if(useInverse)
      Warp->getParamInverse(adpt,dpt);
    else
      dpt=adpt;
    Warp->pRondp(tp,dpt,p2);
  }
  else
  {
    p2=tp+alpha*direction;
  }
  vpColVector p3(nbParam);
  ptp[0]=&p0;
  ptp[1]=&p1;
  ptp[2]=&p2;
  ptp[3]=&p3;


  double *Cost=new double[4];
  //Cost[0]=getCost(I,p0);
  Cost[0]=tMI;
  Cost[1]=getCost(I,p1);
  Cost[2]=getCost(I,p2);


  double *talpha=new double[4];
  talpha[0]=0;
  talpha[1]=1.;
  talpha[2]=alpha;

  //for(int i=0;i<3;i++)
  //	std::cout<<"alpha["<<i<<"] = "<<talpha[i]<<"   Cost["<<i<<"] = "<<Cost[i]<<std::endl;

  //Utilise trois estimï¿œes de paraboles succesive ...
  //A changer pour rendre adaptable
  for(unsigned int opt=0;opt<nbIterBrent;opt++)
  {
    //double a=talpha[0];
    //double b=talpha[1];
    //double c=talpha[2];
    //double Cost0=Cost[0];
    //double Cost1=Cost[1];
    //double Cost2=Cost[2];

    vpMatrix A(3,3);
    for(unsigned int i=0;i<3;i++){A[i][0]=talpha[i]*talpha[i];A[i][1]=talpha[i];A[i][2]=1.;}
    //std::cout<<"A="<<A<<std::endl;
    vpColVector B(3);for(unsigned int i=0;i<3;i++)B[i]=Cost[i];
    vpColVector parabol(3);parabol=(A.t()*A).inverseByLU()*A.t()*B;
    //vpColVector parabol(3);parabol=A.pseudoInverse()*B;

    //si convexe
    if(parabol[0]>0)
    {
      talpha[3]=-0.5*parabol[1]/parabol[0];
      //std::cout<<"parabol = "<<parabol<<std::endl;
      //std::cout<<"convexe talpha = "<<talpha[3]<<std::endl;
    }
    else//si concave
    {
      int tindic_x_min=0;
      int tindic_x_max=0;
      for(int i=1;i<3;i++)
      {
        if(talpha[i]<talpha[tindic_x_min])
          tindic_x_min=i;
        if(talpha[i]>talpha[tindic_x_max])
          tindic_x_max=i;
      }

      if(Cost[tindic_x_max]<Cost[tindic_x_min])
      {
        //talpha[3]=talpha[tindic_x_max]+1.;
        talpha[3]=talpha[tindic_x_max]+1.;
        /*if(talpha[tindic_x_min]>talpha[tindic_x_max])
          talpha[3]=talpha[tindic_x_min]+1.;
        else
          talpha[3]=talpha[tindic_x_min]-1.;*/
      }
      else
      {
        //talpha[3]=talpha[tindic_x_min]-1.;
        talpha[3]=talpha[tindic_x_min]-1.;
        /*if(talpha[tindic_x_min]<talpha[tindic_x_max])
          talpha[3]=talpha[tindic_x_max]+1.;
        else
          talpha[3]=talpha[tindic_x_max]-1.;*/
      }
      //std::cout<<"concave talpha="<<talpha[3]<<std::endl;
    }
    //std::cout<<"talpha="<<talpha[3]<<std::endl;
    int indic_x_min=0;
    int indic_x_max=0;
    for(int i=1;i<3;i++)
    {
      if(talpha[i]<talpha[indic_x_min])
        indic_x_min=i;
      if(talpha[i]>talpha[indic_x_max])
        indic_x_max=i;
    }
    //std::cout<<"talpha = "<<talpha[3]<<std::endl;
    if(talpha[3]>talpha[indic_x_max])
      if((talpha[3]-talpha[indic_x_max])>alpha)talpha[3]=talpha[indic_x_max]+4.;
    if(talpha[3]<talpha[indic_x_min])
      if((talpha[indic_x_min]-talpha[3])>alpha)talpha[3]=talpha[indic_x_min]-4.;

    /*if(((b-a)*(Cost1-Cost2)-(b-c)*(Cost1-Cost0))==0)
    {Cost[3]=1000;break;}

    //calcul du gain correspondant au minimum de la parabole estimï¿œe
    talpha[3]=b-0.5*((b-a)*(b-a)*(Cost1-Cost2)-(b-c)*(b-c)*(Cost1-Cost0))/((b-a)*(Cost1-Cost2)-(b-c)*(Cost1-Cost0));
    int indic_x_min=0;
    int indic_x_max=0;
    for(int i=1;i<3;i++)
    {
      if(talpha[i]<talpha[indic_x_min])
        indic_x_min=i;
      if(talpha[i]>talpha[indic_x_max])
        indic_x_max=i;
    }
    std::cout<<"talpha = "<<talpha[3]<<std::endl;
    if(talpha[3]>talpha[indic_x_max])
      if((talpha[3]-talpha[indic_x_max])>alpha)talpha[3]=talpha[indic_x_max]+alpha;
    if(talpha[3]<talpha[indic_x_min])
      if((talpha[indic_x_min]-talpha[3])>alpha)talpha[3]=talpha[indic_x_min]-alpha;*/

    //p3=tp-talpha[3]*direction;
    if(useCompositionnal)
    {
      adpt=talpha[3]*direction;
      if(useInverse)
        Warp->getParamInverse(adpt,dpt);
      else
        dpt=adpt;
      Warp->pRondp(tp,dpt,p3);
    }
    else
    {
      p3=tp+talpha[3]*direction;
    }

    Cost[3]=getCost(I,p3);
    //std::cout<<"new cost="<<Cost[3]<<std::endl;

    int indice_f_max=0;
    for(int i=1;i<4;i++)
      if(Cost[i]>Cost[indice_f_max])
        indice_f_max=i;
    if(indice_f_max!=3)
    {
      *ptp[indice_f_max]=*ptp[3];
      Cost[indice_f_max]=Cost[3];
      talpha[indice_f_max]=talpha[3];
    }
    else
      break;
  }

  int indice_f_min=0;
  for(int i=0;i<4;i++)
    if(Cost[i]<Cost[indice_f_min])
      indice_f_min=i;

  alpha=talpha[indice_f_min];

  if(alpha<1)alpha=1.;

  delete[] ptp;
  delete[] Cost;
  delete[] talpha;
}