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(); }
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 }
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; }