void DiffractionDataSingleCrystal::CalcIcalc() const
{
   TAU_PROFILE("DiffractionData::CalcIcalc()","void ()",TAU_DEFAULT);
   VFN_DEBUG_MESSAGE("DiffractionData::CalcIcalc():"<<this->GetName(),3)
   this->GetFhklCalcSq();
   if( (mClockStructFactorSq<mClockIcalc) && (mClockScaleFactor<mClockIcalc)
        && ((0==mGroupOption.GetChoice()) || (mClockPrepareTwinningCorr<mClockIcalc)) ) return;

   mCalcIntensity=mFhklCalcSq;
   mCalcIntensity*=mScaleFactor;
   if(0!=mGroupOption.GetChoice())
   {
      if(1==mGroupOption.GetChoice()) this->PrepareTwinningCalc();
      mGroupIcalc.resize(mNbGroup);
      mGroupIcalc=0;
      long first=0;
      for(long i=0;i<mNbGroup;i++)
      {
         //cout<<"Group #"<<i<<":"<<first<<"->"<<mGroupIndex(i)<<endl;
         for(long j=first;j<mGroupIndex(i);j++)
         {
            //cout <<"       " << mIntH(j)<<" "<< mIntK(j)<<" "<< mIntL(j)<<" " << mCalcIntensity(j)<<endl;
            mGroupIcalc(i)+=mCalcIntensity(j);
         }
         first=mGroupIndex(i);
         //cout  << "   => Icalc="<< mGroupIcalc(i) <<" , Iobs="<< mGroupIobs(i)<<endl<<endl;
      }
   }
   mClockIcalc.Click();
}
REAL DiffractionDataSingleCrystal::GetBestRFactor() const
{
   TAU_PROFILE("DiffractionData::GetBestRFactor()","void ()",TAU_DEFAULT);
   VFN_DEBUG_MESSAGE("DiffractionData::GetBestRFactor()",3);
   this->FitScaleFactorForR();
   return this->GetR();
}
void DiffractionDataSingleCrystal::CalcIcalc_FullDeriv(std::set<RefinablePar *> &vPar)
{
   TAU_PROFILE("DiffractionDataSingleCrystal::CalcIcalc_FullDeriv()","void ()",TAU_DEFAULT);
   this->GetFhklCalcSq_FullDeriv(vPar);
   // :TODO: instead of clear(), only add/remove when necessary ?
   mCalcIntensity_FullDeriv.clear();
   mCalcIntensity_FullDeriv=mFhklCalcSq_FullDeriv;
   //:TODO: multiplication only up to mNbReflUsed
   for(std::map<RefinablePar*, CrystVector_REAL>::iterator pos=mCalcIntensity_FullDeriv.begin(); pos!=mCalcIntensity_FullDeriv.end();pos++)
   {
      if(pos->first==0)
      {// This is Icalc, not derived
         pos->second *=mScaleFactor;
         continue;
      }
      if(pos->first->GetPointer()!=&mScaleFactor)
      {
         /*if(pos->second.size()>0) */ // not needed
         pos->second *=mScaleFactor;
      }
      else
      {
         pos->second=mFhklCalcSq;
      }
   }

   if(0!=mGroupOption.GetChoice())
   {//:TODO:
      if(1==mGroupOption.GetChoice()) this->PrepareTwinningCalc();
      // :TODO: instead of clear(), only add/remove when necessary ?
      mGroupIcalc_FullDeriv.clear();
      for(std::map<RefinablePar*, CrystVector_REAL>::iterator pos=mCalcIntensity_FullDeriv.begin(); pos!=mCalcIntensity_FullDeriv.end();pos++)
      {
         mGroupIcalc_FullDeriv[pos->first].resize(mNbGroup);
         mGroupIcalc_FullDeriv[pos->first]=0;
         long first=0;

         for(long i=0;i<mNbGroup;i++)
         {
            for(long j=first;j<mGroupIndex(i);j++)
            {
               mGroupIcalc_FullDeriv[pos->first](i)+=mCalcIntensity_FullDeriv[pos->first](j);
            }
            first=mGroupIndex(i);
         }
      }
   }
}
void DiffractionDataSingleCrystal::FitScaleFactorForRw() const
{
   TAU_PROFILE("DiffractionData::FitScaleFactorForRw()","void ()",TAU_DEFAULT);
   VFN_DEBUG_MESSAGE("DiffractionData::FitScaleFactorForRw()",3);
   if(mHasObservedData==false)
   {//throw exception here ?
      return;
      //throw ObjCrystException("DiffractionData::FitScaleFactorForRw() Cannot compute Rw
      //   or scale factor: there is no observed data !");
   }
   REAL tmp1=0;
   REAL tmp2=0;
   const REAL *p1;
   const REAL *p2;
   const REAL *p3;
   long nb;
   if(mGroupOption.GetChoice()==0)
   {
      p1=mCalcIntensity.data();
      p2=mObsIntensity.data();
      p3=mWeight.data();
      nb=mNbReflUsed;
   }
   else
   {
      p1=mGroupIcalc.data();
      p2=mGroupIobs.data();
      p3=mGroupWeight.data();
      nb=mGroupIobs.numElements();
   }

   for(long i=nb;i>0;i--)
   {
      tmp1 += *p3 * (*p1) * (*p2++);
      tmp2 += *p3++ * (*p1) * (*p1);
      p1++;
   }
   mScaleFactor      *= tmp1/tmp2;
   mClockScaleFactor.Click();

   mCalcIntensity *= tmp1/tmp2;
   if(0!=mGroupOption.GetChoice()) mGroupIcalc*= tmp1/tmp2;
   mClockIcalc.Click();
}
REAL DiffractionDataSingleCrystal::GetRw()const
{
   TAU_PROFILE("DiffractionData::Rw()"," REAL()",TAU_DEFAULT);
   VFN_DEBUG_MESSAGE("DiffractionData::Rw()",3);
   if(mHasObservedData==false)
   {
      return 0;
   }
   REAL tmp1=0;
   REAL tmp2=0;
   const REAL *p1;
   const REAL *p2;
   const REAL *p3;
   long nb;
   if(mGroupOption.GetChoice()==0)
   {
      p1=mCalcIntensity.data();
      p2=mObsIntensity.data();
      p3=mWeight.data();
      nb=mNbReflUsed;
   }
   else
   {
      p1=mGroupIcalc.data();
      p2=mGroupIobs.data();
      p3=mGroupWeight.data();
      nb=mGroupIobs.numElements();
   }

   for(long i=nb;i>0;i--)
   {
      tmp1 += *p3 * ( *p1 - *p2) * ( *p1 - *p2);
      tmp2 += *p3 * *p2 * *p2;
      p1++;p2++;p3++;
   }
   tmp1=sqrt(tmp1/tmp2);
   VFN_DEBUG_MESSAGE("DiffractionData::Rw()="<<tmp1,3);
   return tmp1 ;// /this->GetNbRefl();
}
예제 #6
0
void AsymmetricUnit::SetSpaceGroup(const SpaceGroup &spg)
{
   VFN_DEBUG_MESSAGE("AsymmetricUnit::SetSpaceGroup(SpGroup)",5)
   tmp_C_Numeric_locale tmploc;
   # if 0
   TAU_PROFILE("(AsymmetricUnit::SetSpaceGroup)","void (SpaceGroup)",TAU_DEFAULT);
   mXmin=0.;
   mYmin=0.;
   mZmin=0.;
   mXmax=1.;
   mYmax=1.;
   mZmax=1.;
   if(1==spg.GetSpaceGroupNumber()) return;//no need to search an asymmetric unit
   // Test points=reular grid of points inside the unit cell
   // All points must be or have at least a symmetric in the asymmetric unit
   const long nbPoints=13;
   CrystMatrix_REAL testPoints(nbPoints*nbPoints*nbPoints,3);
   {
      long l=0;
      for(long i=0;i<nbPoints;i++)
         for(long j=0;j<nbPoints;j++)
            for(long k=0;k<nbPoints;k++)
            {
               testPoints(l  ,0)=i/(REAL)nbPoints;
               testPoints(l  ,1)=j/(REAL)nbPoints;
               testPoints(l++,2)=k/(REAL)nbPoints;
            }
   }
   testPoints += 0.01;

   CrystVector_REAL vert(8);//vertices limits
   vert(0)=1/8.; vert(1)=1/6.; vert(2)=1/4.; vert(3)=1/3.;
   vert(4)=1/2.; vert(5)=2/3.; vert(6)=3/4.; vert(7)=1.;

   const int NbStep=vert.numElements();

   CrystMatrix_REAL coords;

   double junk;

   REAL minVolume=1.;

   bool allPtsInAsym,tmp;
   for(long nx=0;nx<NbStep;nx++)
      for(long ny=0;ny<NbStep;ny++)
         for(long nz=0;nz<NbStep;nz++)
         {
            if(minVolume<(vert(nx)*vert(ny)*vert(nz)-.0001)) break;
            allPtsInAsym=true;
            for(int i=0;i<testPoints.rows();i++)
            {
               coords=spg.GetAllSymmetrics(testPoints(i,0),testPoints(i,1),testPoints(i,2));
               for(long j=0;j<coords.numElements();j++) coords(j)=modf(coords(j)+10.,&junk) ;
               tmp=false;
               for(long j=0;j<coords.rows();j++)
               {//Test if at least one of the symmetrics is in the parallelepiped
                  if(  (coords(j,0) < vert(nx))
                     &&(coords(j,1) < vert(ny))
                     &&(coords(j,2) < vert(nz)))
                  {
                     //cout  << modf(coords(j,0)+10.,junk) << " "
                     //      << modf(coords(j,1)+10.,junk) << " "
                     //      << modf(coords(j,2)+10.,junk) << endl;
                     tmp=true;
                     break;
                  }
               }
               if(false==tmp)
               {
                  //cout << " Rejected:"<<vert(nx)<<" "<<vert(ny)<<" "<<vert(nz)<<" "<<i<<endl;
                  //cout << coords <<endl;
                  allPtsInAsym=false;
                  break;
               }
            }
            if( (true==allPtsInAsym))
            {
               mXmax=vert(nx);
               mYmax=vert(ny);
               mZmax=vert(nz);
               VFN_DEBUG_MESSAGE("->ACCEPTED:" << mXmax <<" "<< mYmax <<" "<< mZmax <<endl,2)
               //cout << "->ACCEPTED:" << mXmax <<" "<< mYmax <<" "<< mZmax <<endl;
               minVolume=vert(nx)*vert(ny)*vert(nz);
               break;//no need to grow any more along z
            }
         }
   cout<<"->Finished Generating (pseudo) Asymmetric Unit, with:"<<endl
       <<"     0 <= x <= "<< mXmax<<endl
       <<"     0 <= y <= "<< mYmax<<endl
       <<"     0 <= z <= "<< mZmax<<endl<<endl;
   #else
   const cctbx::sgtbx::brick b(spg.GetCCTbxSpg().type());
   #ifdef __DEBUG__
   cout<<"->>Parallelepipedic Asymmetric Unit, from cctbx::sgtbx::brick:"<<endl
       <<b.as_string()<<endl;
   #endif
   mXmin=boost::rational_cast<REAL,int>(b(0,0).value());
   mYmin=boost::rational_cast<REAL,int>(b(1,0).value());
   mZmin=boost::rational_cast<REAL,int>(b(2,0).value());
   mXmax=boost::rational_cast<REAL,int>(b(0,1).value());
   mYmax=boost::rational_cast<REAL,int>(b(1,1).value());
   mZmax=boost::rational_cast<REAL,int>(b(2,1).value());

   #endif
}
예제 #7
0
파일: convect.C 프로젝트: 8l/rose
int 
main(int argc, char** argv)
{
  ios::sync_with_stdio();

#ifdef USE_TAU
  TAU_PROFILE_INIT(argc,argv);
  TAU_PROFILE("main","int (int argc, char** argv)",TAU_DEFAULT);
  TAU_PROFILE_TIMER(loop_timer,"Computation Loop","", TAU_USER);
  TAU_PROFILE_TIMER(bc_timer,"Boundary Condition","", TAU_USER);
  TAU_PROFILE_TIMER(update_timer,"Ghost Boundary Update","", TAU_USER);
  TAU_PROFILE_TIMER(copy_timer,"Array Copy","", TAU_USER);
#endif

  int Number_of_Processors=0;
  
  Optimization_Manager::setForceVSG_Update(Off);
  Optimization_Manager::Initialize_Virtual_Machine("",Number_of_Processors,argc,argv);
  Partitioning_Type::SpecifyDefaultInternalGhostBoundaryWidths(1);
  Optimization_Manager::setForceVSG_Update(Off);
  
  Index::setBoundsCheck(off);

  int myid = Communication_Manager::My_Process_Number;
  int numProcs = Communication_Manager::Number_Of_Processors;
  
  const int Xsize=1003*numProcs, Ysize=1003;

  const Range ix(-1,Xsize-2), iy(-1,Ysize-2), all;
  const Range ix1(0,Xsize-3), iy1(0,Ysize-3);
  
  Partitioning_Type thePartition;
  thePartition.SpecifyDecompositionAxes(1);

  doubleArray A(ix,iy), old_A(ix,iy), x(ix,iy), y(ix,iy), temp(ix,iy);
  const double dx=1./(Xsize-3), dy=1./(Ysize-3), dt=0.1/(Xsize+Ysize);
  double theTime=0.0,maxError;
  
  A.partition(thePartition);
  old_A.partition(thePartition);
  temp.partition(thePartition);
  x.partition(thePartition);
  y.partition(thePartition);
  
  intSerialArray theProcessorSet = (A.getPartition()).getProcessorSet();  
  
  doubleSerialArray xlocal = x.getLocalArray();
  doubleSerialArray ylocal = y.getLocalArray();  
  
  cout<<"size of xlocal: "<<xlocal.getSize()<<endl;
  
  Optimization_Manager::setOptimizedScalarIndexing(On);
  for( int i=xlocal.getBase(0);i<=xlocal.getBound(0);i++)
    xlocal(i,all) = dx*i;

  for( int j=ylocal.getBase(1);j<=ylocal.getBound(1);j++)
    ylocal(all,j) = dy*j;
  Optimization_Manager::setOptimizedScalarIndexing(Off);

  x.updateGhostBoundaries();
  y.updateGhostBoundaries();  

  A = (1.0 + theTime)*(2.0 + x + y);

  doubleSerialArray oldALocal = old_A.getLocalArray();
  doubleSerialArray ALocal = A.getLocalArray();
  doubleSerialArray tempLocal = temp.getLocalArray();

  int iLower = (myid>0)?ALocal.getBase(0)+1:ALocal.getBase(0)+1;
  int iUpper = (myid<numProcs-1)?ALocal.getBound(0)-1:ALocal.getBound(0)-1;
  int jLower = ALocal.getBase(1)+1;
  int jUpper = ALocal.getBound(1)-1;
  
  Range ILocInterior(iLower,iUpper);
  Range JLocInterior(jLower,jUpper);
  
  iLower = (myid>0)?ALocal.getBase(0)+1:ALocal.getBase(0);
  iUpper = (myid<numProcs-1)?ALocal.getBound(0)-1:ALocal.getBound(0);
  jLower = ALocal.getBase(1);
  jUpper = ALocal.getBound(1);
  
  Range ILoc(iLower,iUpper);
  Range JLoc(jLower,jUpper);

  if (myid == 0)  
    cout << "-----Starting computation" << endl; 

  double t = MPI_Wtime();

#ifdef USE_TAU
  TAU_PROFILE_START(copy_timer);
#endif

  oldALocal = ALocal;

#ifdef USE_TAU
  TAU_PROFILE_STOP(copy_timer);
  TAU_PROFILE_START(update_timer);
#endif
  
  old_A.updateGhostBoundaries();

#ifdef USE_TAU
  TAU_PROFILE_STOP(update_timer);
  TAU_PROFILE_START(loop_timer);
#endif

  tempLocal(ILocInterior,JLocInterior) = ALocal(ILocInterior,JLocInterior) -
    dt*( ( ALocal(ILocInterior+1,JLocInterior) - ALocal(ILocInterior-1,JLocInterior) ) / (2.0*dx) + 
         ( ALocal(ILocInterior,JLocInterior+1) - ALocal(ILocInterior,JLocInterior-1) ) / (2.0*dy) -
         (4.0 + 2.0*theTime + xlocal(ILocInterior,JLocInterior) + ylocal(ILocInterior,JLocInterior)) );
  
#ifdef USE_TAU
  TAU_PROFILE_STOP(loop_timer);
  TAU_PROFILE_START(copy_timer);
#endif

  //
  // copy temp into A
  //
  ALocal(ILocInterior,JLocInterior) = tempLocal(ILocInterior,JLocInterior);
  
#ifdef USE_TAU
  TAU_PROFILE_STOP(copy_timer);
  TAU_PROFILE_START(bc_timer);
#endif

  A(all,Ysize-2) = (1.0+(theTime+dt))*(2.0+x(all,Ysize-2)+y(all,Ysize-2));
  A(all,-1) = (1.0+(theTime+dt))*(2.0+x(all,-1)+y(all,-1));
  A(-1,iy1) = (1.0+(theTime+dt))*(2.0+x(-1,iy1)+y(-1,iy1));
  A(Xsize-2,iy1) = (1.0+(theTime+dt))*(2.0+x(Xsize-2,iy1)+y(Xsize-2,iy1));

#ifdef USE_TAU
  TAU_PROFILE_STOP(bc_timer);
  TAU_PROFILE_START(update_timer);
#endif

  A.updateGhostBoundaries();

#ifdef USE_TAU
  TAU_PROFILE_STOP(update_timer);
#endif

  theTime += dt;
  
  for (int k = 0; k<100; k++)
  {
      
#ifdef USE_TAU
    TAU_PROFILE_START(loop_timer);
#endif

    tempLocal(ILocInterior,JLocInterior) = oldALocal(ILocInterior,JLocInterior) - 
      2.*dt*( ( ALocal(ILocInterior+1,JLocInterior) - ALocal(ILocInterior-1,JLocInterior) ) / (2.0*dx) + 
              ( ALocal(ILocInterior,JLocInterior+1) - ALocal(ILocInterior,JLocInterior-1) ) / (2.0*dy) -
              (4.0 + 2.0*theTime + xlocal(ILocInterior,JLocInterior) + ylocal(ILocInterior,JLocInterior))  );


#ifdef USE_TAU
    TAU_PROFILE_STOP(loop_timer);
    TAU_PROFILE_START(copy_timer);
#endif

    oldALocal(ILoc,JLoc) = ALocal(ILoc,JLoc);
    ALocal(ILoc,JLoc) = tempLocal(ILoc,JLoc);

#ifdef USE_TAU
    TAU_PROFILE_STOP(copy_timer);
    TAU_PROFILE_START(bc_timer);
#endif

    A(all,Ysize-2) = (1.0+(theTime+dt))*(2.0+x(all,Ysize-2)+y(all,Ysize-2));
    A(all,-1) = (1.0+(theTime+dt))*(2.0+x(all,-1)+y(all,-1));
    A(-1,iy1) = (1.0+(theTime+dt))*(2.0+x(-1,iy1)+y(-1,iy1));
    A(Xsize-2,iy1) = (1.0+(theTime+dt))*(2.0+x(Xsize-2,iy1)+y(Xsize-2,iy1));
  
#ifdef USE_TAU
    TAU_PROFILE_STOP(bc_timer);
    TAU_PROFILE_START(update_timer);
#endif

    A.updateGhostBoundaries();

#ifdef USE_TAU
  TAU_PROFILE_STOP(update_timer);
#endif

    theTime += dt;
  }
  t = MPI_Wtime() - t;
  double maxTime;

  MPI_Reduce(&t, &maxTime, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);

  if (myid == 0)  
  {
    cout << "   Total Time= " << maxTime<< " s" << endl; 
  }
  
  maxError = max(fabs(A(ix,iy)-(1.0+theTime)*(2.0+x(ix,iy)+y(ix,iy))));
  if (myid == 0)  
  {
    cout << "max error at t="<<theTime<<"  is: "<<maxError<<endl;
    cout << "number of messages sent= "<<Diagnostic_Manager::getNumberOfMessagesSent()<<endl;
    cout << "number of messages received= "<<Diagnostic_Manager::getNumberOfMessagesReceived()<<endl;

    ofstream OutFile;
    OutFile.open("/p/gb1/bmiller/ConvectPpp/ConvectPppNew.ConstSizePerProc.out",ios::app);
    OutFile << numProcs << "  " << maxTime << "  " << maxError << endl;
    OutFile.close();
  }

#ifdef USE_TAU
  TAU_PROFILE_EXIT("Finishing Profiling.");
#endif

  Optimization_Manager::Exit_Virtual_Machine();

  return 0;
}
REAL DiffractionDataSingleCrystal::GetChi2()const
{
   if(mHasObservedData==false)
   {
      mChi2=0;
      return mChi2;
   }
   this->GetNbReflBelowMaxSinThetaOvLambda();
   if(mClockChi2>mClockMaster) return mChi2;

   this->CalcIcalc();
   if(mClockChi2>mClockIcalc) return mChi2;

   TAU_PROFILE("DiffractionData::Chi2()"," REAL()",TAU_DEFAULT);
   VFN_DEBUG_ENTRY("DiffractionData::Chi2()",3);
   this->FitScaleFactorForRw();
   mChi2=0;
   const REAL *p1;
   const REAL *p2;
   const REAL *p3;
   long nb;
   if(mGroupOption.GetChoice()==0)
   {
      p1=mCalcIntensity.data();
      p2=mObsIntensity.data();
      p3=mWeight.data();
      nb=mNbReflUsed;
   }
   else
   {
      p1=mGroupIcalc.data();
      p2=mGroupIobs.data();
      p3=mGroupWeight.data();
      nb=mGroupIobs.numElements();
   }

   for(long i=nb;i>0;i--)
   {
      mChi2 += *p3++ * ( *p1 - *p2) * ( *p1 - *p2);
      p1++;p2++;
   }
   /*
   // SSE code gives about 30% faster code on P3 (tested with 10000 reflections),
   // but scarcely any improvement on athlon-xp
   union sse4f
   {
      __m128 m128;
      struct
      {
         float x, y, z, w;
      };
   } ;
   const long nb=mNbReflUsed/4;
   const float* p1=mCalcIntensity.data();
   const float* p2=mObsIntensity.data();
   const float* p3=mWeight.data();
   for(long i=0;i<nb;i++)
   {
      //segfaults with _mm_load_ps() instead of _mm_loadu_ps? Alignment problem ?
      __m128 a = _mm_sub_ps(_mm_loadu_ps(p1),_mm_loadu_ps(p2));
      union sse4f b;
      b.m128= _mm_mul_ps(_mm_loadu_ps(p3),_mm_mul_ps(a,a));
      mChi2 += b.x+b.y+b.z+b.w;
      p1+=4;p2+=4;p3+=4;
   }
   p1-=4;p2-=4;p3-=4;
   for(long i=nb*4;i<mNbReflUsed;i++)
   {
      mChi2 += *p3++ * ( *p1 - *p2) * ( *p1 - *p2);
      p1++;p2++;
   }
   */
   mClockChi2.Click();
   VFN_DEBUG_EXIT("DiffractionData::Chi2()="<<mChi2,3);
   return mChi2;
}
CrystVector_long DiffractionDataSingleCrystal::SortReflectionBySinThetaOverLambda(const REAL maxSTOL)
{
   TAU_PROFILE("DiffractionDataSingleCrystal::SortReflectionBySinThetaOverLambda()","void ()",TAU_DEFAULT);
   VFN_DEBUG_ENTRY("DiffractionDataSingleCrystal::SortReflectionBySinThetaOverLambda()",5)
   // ScatteringData::SortReflectionBySinThetaOverLambda only sorts H,K,L and multiplicity.
   CrystVector_long index=this->ScatteringData::SortReflectionBySinThetaOverLambda(maxSTOL);

   if(mObsIntensity.numElements()==mNbRefl)
   {
      CrystVector_REAL tmpObs,tmpSigma,tmpWeight;
      tmpObs=mObsIntensity;
      tmpSigma=mObsSigma;
      tmpWeight=mWeight;
      for(long i=0;i<mNbRefl;i++)
      {
         mObsIntensity(i)=tmpObs(index(i));
         mObsSigma(i)=tmpSigma(index(i));
         mWeight(i)=tmpWeight(index(i));
      }
      // Keep a copy as squared F(hkl), to enable fourier maps
      // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
      mFhklObsSq=mObsIntensity;
      mClockFhklObsSq.Click();

      if(mGroupOption.GetChoice()==2)
      {
         CrystVector_long tmp;//,oldgroup(mNbGroup);;
         tmp=mGroupIndex;
         for(long i=0;i<mNbRefl;i++) mGroupIndex(i)=tmp(index(i));
         /*
         for(long i=0;i<mNbRefl;i++)
            cout<<mIntH(i)<<" "<<mIntK(i)<<" "<<mIntL(i)<<" "
                <<mObsIntensity(i)<<" "<<mObsSigma(i)<<" "<<mWeight(i)<< ":"<<mGroupIndex(i)<<endl;
         */
         // Now re-index the groups of reflections in
         // ascending order
         {
            index.resize(mNbGroup);
            index=-1;
            long group=0;
            CrystVector_REAL oldGroupIobs, oldGroupWeight,oldGroupSigma;
            oldGroupIobs  =mGroupIobs;
            oldGroupWeight=mGroupWeight;
            oldGroupSigma=mGroupSigma;
            for(long i=0;i<mNbRefl;i++)
            {
               if(index(mGroupIndex(i))==-1)// first reflection of a group ?
               {
                  mGroupIobs(group)=oldGroupIobs(mGroupIndex(i));
                  mGroupSigma(group)=oldGroupSigma(mGroupIndex(i));
                  mGroupWeight(group)=oldGroupWeight(mGroupIndex(i));
                  //oldgroup(group)=mGroupIndex(i);
                  index(mGroupIndex(i))=group++;
               }
               mGroupIndex(i)=index(mGroupIndex(i));
            }
         }
         /*
         cout<<mIntH.numElements()<<","
             <<mIntK.numElements()<<","
             <<mIntL.numElements()<<","
             <<oldgroup.numElements()<<","<<mGroupIndex.numElements()<<endl;
         for(long i=0;i<mNbRefl;i++)
            cout<<mIntH(i)<<" "<<mIntK(i)<<" "<<mIntL(i)<<endl
                <<"             :"<<oldgroup(mGroupIndex(i))<<"->"<<mGroupIndex(i)<<endl;
         */
         // Now re-group the reflections
         index=SortSubs(mGroupIndex);
         {
            CrystVector_long oldH,oldK,oldL,oldMult;
            oldH=mH;
            oldK=mK;
            oldL=mL;
            oldMult=mMultiplicity;
            tmpObs=mObsIntensity;
            tmpSigma=mObsSigma;
            tmpWeight=mWeight;
            for(long i=0;i<mNbRefl;i++)
            {
               const long subs=index(i);
               mH(i)=oldH(subs);
               mK(i)=oldK(subs);
               mL(i)=oldL(subs);
               mMultiplicity(i)=oldMult(subs);
               mObsIntensity(i)=tmpObs(subs);
               mObsSigma(i)=tmpSigma(subs);
               mWeight(i)=tmpWeight(subs);
            }
            mClockHKL.Click();
            this->PrepareHKLarrays();
            this->CalcSinThetaLambda();
         }

         // re-write mGroupIndex so that it marks the
         // last reflection of each group.
         index=mGroupIndex;
         mGroupIndex.resize(mNbGroup);
         long group=0;
         for(long i=0;i<mNbRefl;i++)
            if(index(i)!=group)
               mGroupIndex(group++)=i;
         mGroupIndex(mNbGroup-1)=mNbRefl;
      }
   }
   else
   {// if there are no observed values, enter dummy ones
      mObsIntensity.resize(mNbRefl);
      mObsSigma.resize(mNbRefl);
      mWeight.resize(mNbRefl);
      mObsIntensity=100.;
      mObsSigma=1.;
      mWeight=1.;
      mFhklObsSq.resize(0);
      mClockFhklObsSq.Click();
   }
   VFN_DEBUG_EXIT("DiffractionDataSingleCrystal::SortReflectionBySinThetaOverLambda()",5)
   return index;
}