// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void VisualizeGBCDPoleFigure::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  // Make sure any directory path is also available as the user may have just typed
  // in a path without actually creating the full path
  QFileInfo fi(getOutputFile());

  QDir dir(fi.path());
  if(!dir.mkpath("."))
  {
    QString ss;
    ss = QObject::tr("Error creating parent path '%1'").arg(dir.path());
    setErrorCondition(-1);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  QFile file(getOutputFile());
  if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
  {
    QString ss = QObject::tr("Error opening output file '%1'").arg(getOutputFile());
    setErrorCondition(-100);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  FloatArrayType::Pointer gbcdDeltasArray = FloatArrayType::CreateArray(5, "GBCDDeltas");
  gbcdDeltasArray->initializeWithZeros();

  FloatArrayType::Pointer gbcdLimitsArray = FloatArrayType::CreateArray(10, "GBCDLimits");
  gbcdLimitsArray->initializeWithZeros();

  Int32ArrayType::Pointer gbcdSizesArray = Int32ArrayType::CreateArray(5, "GBCDSizes");
  gbcdSizesArray->initializeWithZeros();

  float* gbcdDeltas = gbcdDeltasArray->getPointer(0);
  int* gbcdSizes = gbcdSizesArray->getPointer(0);
  float* gbcdLimits = gbcdLimitsArray->getPointer(0);

  // Original Ranges from Dave R.
  //m_GBCDlimits[0] = 0.0f;
  //m_GBCDlimits[1] = cosf(1.0f*m_pi);
  //m_GBCDlimits[2] = 0.0f;
  //m_GBCDlimits[3] = 0.0f;
  //m_GBCDlimits[4] = cosf(1.0f*m_pi);
  //m_GBCDlimits[5] = 2.0f*m_pi;
  //m_GBCDlimits[6] = cosf(0.0f);
  //m_GBCDlimits[7] = 2.0f*m_pi;
  //m_GBCDlimits[8] = 2.0f*m_pi;
  //m_GBCDlimits[9] = cosf(0.0f);

  // Greg R. Ranges
  gbcdLimits[0] = 0.0f;
  gbcdLimits[1] = 0.0f;
  gbcdLimits[2] = 0.0f;
  gbcdLimits[3] = 0.0f;
  gbcdLimits[4] = 0.0f;
  gbcdLimits[5] = SIMPLib::Constants::k_PiOver2;
  gbcdLimits[6] = 1.0f;
  gbcdLimits[7] = SIMPLib::Constants::k_PiOver2;
  gbcdLimits[8] = 1.0f;
  gbcdLimits[9] = SIMPLib::Constants::k_2Pi;

  // reset the 3rd and 4th dimensions using the square grid approach
  gbcdLimits[3] = -sqrtf(SIMPLib::Constants::k_PiOver2);
  gbcdLimits[4] = -sqrtf(SIMPLib::Constants::k_PiOver2);
  gbcdLimits[8] = sqrtf(SIMPLib::Constants::k_PiOver2);
  gbcdLimits[9] = sqrtf(SIMPLib::Constants::k_PiOver2);

  // get num components of GBCD
  QVector<size_t> cDims = m_GBCDPtr.lock()->getComponentDimensions();

  gbcdSizes[0] = cDims[0];
  gbcdSizes[1] = cDims[1];
  gbcdSizes[2] = cDims[2];
  gbcdSizes[3] = cDims[3];
  gbcdSizes[4] = cDims[4];

  gbcdDeltas[0] = (gbcdLimits[5] - gbcdLimits[0]) / float(gbcdSizes[0]);
  gbcdDeltas[1] = (gbcdLimits[6] - gbcdLimits[1]) / float(gbcdSizes[1]);
  gbcdDeltas[2] = (gbcdLimits[7] - gbcdLimits[2]) / float(gbcdSizes[2]);
  gbcdDeltas[3] = (gbcdLimits[8] - gbcdLimits[3]) / float(gbcdSizes[3]);
  gbcdDeltas[4] = (gbcdLimits[9] - gbcdLimits[4]) / float(gbcdSizes[4]);

  float vec[3] = { 0.0f, 0.0f, 0.0f };
  float vec2[3] = { 0.0f, 0.0f, 0.0f };
  float rotNormal[3] = { 0.0f, 0.0f, 0.0f };
  float rotNormal2[3] = { 0.0f, 0.0f, 0.0f };
  float sqCoord[2] = { 0.0f, 0.0f };
  float dg[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dgt[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dg1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dg2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym2t[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float mis_euler1[3] = { 0.0f, 0.0f, 0.0f };

  float misAngle = m_MisorientationRotation.angle * SIMPLib::Constants::k_PiOver180;
  float normAxis[3] = { m_MisorientationRotation.h, m_MisorientationRotation.k, m_MisorientationRotation.l };
  MatrixMath::Normalize3x1(normAxis);
  // convert axis angle to matrix representation of misorientation
  FOrientArrayType om(9, 0.0f);
  FOrientTransformsType::ax2om(FOrientArrayType(normAxis[0], normAxis[1], normAxis[2], misAngle), om);
  om.toGMatrix(dg);

  // take inverse of misorientation variable to use for switching symmetry
  MatrixMath::Transpose3x3(dg, dgt);

  // Get our SpaceGroupOps pointer for the selected crystal structure
  SpaceGroupOps::Pointer orientOps = m_OrientationOps[m_CrystalStructures[m_PhaseOfInterest]];

  // get number of symmetry operators
  int32_t n_sym = orientOps->getNumSymOps();

  int32_t xpoints = 100;
  int32_t ypoints = 100;
  int32_t zpoints = 1;
  int32_t xpointshalf = xpoints / 2;
  int32_t ypointshalf = ypoints / 2;
  float xres = 2.0f / float(xpoints);
  float yres = 2.0f / float(ypoints);
  float zres = (xres + yres) / 2.0;
  float x = 0.0f, y = 0.0f;
  float sum = 0;
  int32_t count = 0;
  bool nhCheck = false;
  int32_t hemisphere = 0;

  int32_t shift1 = gbcdSizes[0];
  int32_t shift2 = gbcdSizes[0] * gbcdSizes[1];
  int32_t shift3 = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2];
  int32_t shift4 = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2] * gbcdSizes[3];

  int64_t totalGBCDBins = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2] * gbcdSizes[3] * gbcdSizes[4] * 2;

  QVector<size_t> dims(1, 1);
  DoubleArrayType::Pointer poleFigureArray = DoubleArrayType::NullPointer();
  poleFigureArray = DoubleArrayType::CreateArray(xpoints * ypoints, dims, "PoleFigure");
  poleFigureArray->initializeWithZeros();
  double* poleFigure = poleFigureArray->getPointer(0);

  for (int32_t k = 0; k < ypoints; k++)
  {
    for (int32_t l = 0; l < xpoints; l++)
    {
      // get (x,y) for stereographic projection pixel
      x = float(l - xpointshalf) * xres + (xres / 2.0);
      y = float(k - ypointshalf) * yres + (yres / 2.0);
      if ((x * x + y * y) <= 1.0)
      {
        sum = 0.0f;
        count = 0;
        vec[2] = -((x * x + y * y) - 1) / ((x * x + y * y) + 1);
        vec[0] = x * (1 + vec[2]);
        vec[1] = y * (1 + vec[2]);
        MatrixMath::Multiply3x3with3x1(dgt, vec, vec2);

        // Loop over all the symetry operators in the given cystal symmetry
        for (int32_t i = 0; i < n_sym; i++)
        {
          //get symmetry operator1
          orientOps->getMatSymOp(i, sym1);
          for (int32_t j = 0; j < n_sym; j++)
          {
            // get symmetry operator2
            orientOps->getMatSymOp(j, sym2);
            MatrixMath::Transpose3x3(sym2, sym2t);
            // calculate symmetric misorientation
            MatrixMath::Multiply3x3with3x3(dg, sym2t, dg1);
            MatrixMath::Multiply3x3with3x3(sym1, dg1, dg2);
            // convert to euler angle
            FOrientArrayType eu(mis_euler1, 3);
            FOrientTransformsType::om2eu(FOrientArrayType(dg2), eu);
            if (mis_euler1[0] < SIMPLib::Constants::k_PiOver2 && mis_euler1[1] < SIMPLib::Constants::k_PiOver2 && mis_euler1[2] < SIMPLib::Constants::k_PiOver2)
            {
              mis_euler1[1] = cosf(mis_euler1[1]);
              // find bins in GBCD
              int32_t location1 = int32_t((mis_euler1[0] - gbcdLimits[0]) / gbcdDeltas[0]);
              int32_t location2 = int32_t((mis_euler1[1] - gbcdLimits[1]) / gbcdDeltas[1]);
              int32_t location3 = int32_t((mis_euler1[2] - gbcdLimits[2]) / gbcdDeltas[2]);
              //find symmetric poles using the first symmetry operator
              MatrixMath::Multiply3x3with3x1(sym1, vec, rotNormal);
              //get coordinates in square projection of crystal normal parallel to boundary normal
              nhCheck = getSquareCoord(rotNormal, sqCoord);
              // Note the switch to have theta in the 4 slot and cos(Phi) int he 3 slot
              int32_t location4 = int32_t((sqCoord[0] - gbcdLimits[3]) / gbcdDeltas[3]);
              int32_t location5 = int32_t((sqCoord[1] - gbcdLimits[4]) / gbcdDeltas[4]);
              if (location1 >= 0 && location2 >= 0 && location3 >= 0 && location4 >= 0 && location5 >= 0 &&
                  location1 < gbcdSizes[0] && location2 < gbcdSizes[1] && location3 < gbcdSizes[2] && location4 < gbcdSizes[3] && location5 < gbcdSizes[4])
              {
                hemisphere = 0;
                if (nhCheck == false) { hemisphere = 1; }
                sum += m_GBCD[(m_PhaseOfInterest * totalGBCDBins) + 2 * ((location5 * shift4) + (location4 * shift3) + (location3 * shift2) + (location2 * shift1) + location1) + hemisphere];
                count++;
              }
            }

            // again in second crystal reference frame
            // calculate symmetric misorientation
            MatrixMath::Multiply3x3with3x3(dgt, sym2, dg1);
            MatrixMath::Multiply3x3with3x3(sym1, dg1, dg2);
            // convert to euler angle
            FOrientTransformsType::om2eu(FOrientArrayType(dg2), eu);
            if (mis_euler1[0] < SIMPLib::Constants::k_PiOver2 && mis_euler1[1] < SIMPLib::Constants::k_PiOver2 && mis_euler1[2] < SIMPLib::Constants::k_PiOver2)
            {
              mis_euler1[1] = cosf(mis_euler1[1]);
              // find bins in GBCD
              int32_t location1 = int32_t((mis_euler1[0] - gbcdLimits[0]) / gbcdDeltas[0]);
              int32_t location2 = int32_t((mis_euler1[1] - gbcdLimits[1]) / gbcdDeltas[1]);
              int32_t location3 = int32_t((mis_euler1[2] - gbcdLimits[2]) / gbcdDeltas[2]);
              // find symmetric poles using the first symmetry operator
              MatrixMath::Multiply3x3with3x1(sym1, vec2, rotNormal2);
              // get coordinates in square projection of crystal normal parallel to boundary normal
              nhCheck = getSquareCoord(rotNormal2, sqCoord);
              // Note the switch to have theta in the 4 slot and cos(Phi) int he 3 slot
              int32_t location4 = int32_t((sqCoord[0] - gbcdLimits[3]) / gbcdDeltas[3]);
              int32_t location5 = int32_t((sqCoord[1] - gbcdLimits[4]) / gbcdDeltas[4]);
              if (location1 >= 0 && location2 >= 0 && location3 >= 0 && location4 >= 0 && location5 >= 0 &&
                  location1 < gbcdSizes[0] && location2 < gbcdSizes[1] && location3 < gbcdSizes[2] && location4 < gbcdSizes[3] && location5 < gbcdSizes[4])
              {
                hemisphere = 0;
                if (nhCheck == false) { hemisphere = 1; }
                sum += m_GBCD[(m_PhaseOfInterest * totalGBCDBins) + 2 * ((location5 * shift4) + (location4 * shift3) + (location3 * shift2) + (location2 * shift1) + location1) + hemisphere];
                count++;
              }
            }
          }
        }
        if (count > 0)
        {
          poleFigure[(k * xpoints) + l] = sum / float(count);
        }
      }
    }
  }

  FILE* f = NULL;
  f = fopen(m_OutputFile.toLatin1().data(), "wb");
  if (NULL == f)
  {
    QString ss = QObject::tr("Error opening output file '%1'").arg(m_OutputFile);
    setErrorCondition(-1);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  // Write the correct header
  fprintf(f, "# vtk DataFile Version 2.0\n");
  fprintf(f, "data set from DREAM3D\n");
  fprintf(f, "BINARY");
  fprintf(f, "\n");
  fprintf(f, "DATASET RECTILINEAR_GRID\n");
  fprintf(f, "DIMENSIONS %d %d %d\n", xpoints + 1, ypoints + 1, zpoints + 1);

  // Write the Coords
  writeCoords(f, "X_COORDINATES", "float", xpoints + 1, (-float(xpoints)*xres / 2.0f), xres);
  writeCoords(f, "Y_COORDINATES", "float", ypoints + 1, (-float(ypoints)*yres / 2.0f), yres);
  writeCoords(f, "Z_COORDINATES", "float", zpoints + 1, (-float(zpoints)*zres / 2.0f), zres);

  int32_t total = xpoints * ypoints * zpoints;
  fprintf(f, "CELL_DATA %d\n", total);

  fprintf(f, "SCALARS %s %s 1\n", "Intensity", "float");
  fprintf(f, "LOOKUP_TABLE default\n");
  {
    float* gn = new float[total];
    float t;
    count = 0;
    for (int32_t j = 0; j < ypoints; j++)
    {
      for (int32_t i = 0; i < xpoints; i++)
      {
        t = float(poleFigure[(j * xpoints) + i]);
        SIMPLib::Endian::FromSystemToBig::convert(t);
        gn[count] = t;
        count++;
      }
    }
    size_t totalWritten = fwrite(gn, sizeof(float), (total), f);
    delete[] gn;
    if (totalWritten != (total))
    {
      QString ss = QObject::tr("Error writing binary VTK data to file '%1'").arg(m_OutputFile);
      setErrorCondition(-1);
      notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
      fclose(f);
      return;
    }
  }
  fclose(f);

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage(getHumanLabel(), "Complete");
}
Beispiel #2
0
int
main (int argc, char ** argv ) 
{
    /*
    ** Loop over the input until EOF, placing a line's worth of tokens
    ** into the list as you go.
    */
    int         nRowChunks        =    0;
	int			nColChunks		  =    0;
    int         nRowsInChunk      =    0;
	int			nColsInChunk	  =    0;
	double	    dbProb			  =  0.0;
	double	    dbZProb			  =  0.0;
	int			nCount            =    0;
	char        szTypesListStr[1024];
	char        szFlags[1024]; 
	int			nTypeCnt 		  =    0;
	int			nIsDense          =    0;
	int			nIsRandom         =    0;
	int			outputInBinary    =    0;

	int  		nCellNum		  =    0;
	int 		nCellMax		  =    0;

	/*
	** Pretty rudimentary checks for argument correctness.
	*/
	if (9 != argc)
		usage(argv[0]);
	
	strncpy(szFlags, argv[1], 1024);
	nRowChunks   = atoi(argv[2]);
	nColChunks   = atoi(argv[3]);
	nRowsInChunk = atoi(argv[4]);
	nColsInChunk = atoi(argv[5]);
	dbProb = atof(argv[6]);
	dbZProb = atof(argv[7]);
	strncpy(szTypesListStr, argv[8], 1024);
	nTypeCnt = strlen(szTypesListStr);

	if (0.1 <= dbProb) 
		nIsDense = 1; 

	/*
	** Some checks for semantic argument correctness 
	*/
	assert(('-' == szFlags[0]));
    assert((1 < strlen(szFlags)));
	assert((0.0 < dbProb));
	assert((1.0 >= dbProb));

	assert((0 < nRowChunks));
	assert((0 < nColChunks));
	assert((0 < nRowsInChunk));
	assert((0 < nColsInChunk));

	for(size_t i = 1,s = strlen(szFlags); i < s; i++) {
		switch(toupper(szFlags[i])) { 
			case 'R':
				nIsRandom = 1; 
		 	break;
			case 'D':
				nIsRandom = 0; 
		 	break;
  		    case 'B':
 				outputInBinary = 1;
			break;
			default:
				usage(argv[0]);
				exit(0);
		 	break;
		}
	}
	/*
	** Some preliminary calculations.
	*/
	nCellMax = nRowChunks * nRowsInChunk * nColChunks * nColsInChunk;
    srandom(time(0));

	if (0 == nIsDense) { 
		/*
		** This is the SPARSE representation.
		*/
		/*
		** How many to step over initially?
		*/
		long nStep = geomdev ( dbProb );

		for ( int i = 0;
              i < nRowChunks;
              i++ ) { 

			for ( int j = 0;
                  j < nColChunks; 
                  j++ ) { 

				if ( 0 == outputInBinary ) { 
					if (i+j) { 

						printf("\n;\n{ %d, %d }[[", 
							i * nRowsInChunk, j * nColsInChunk);

					} else { 

						printf("{ %d, %d }[[",
							i * nRowsInChunk, j * nColsInChunk);

					}
				}

				nCount = 0;
				int firstInChunk = 1;
				
				/*
				** ROWS in the CHUNK	
				*/
				for (int n = 0;
					 n < nRowsInChunk; 
					 n++) { 

					for (int m = 0; 
						 m < nColsInChunk; 
						 m+=0 ) { 

						nCellNum = (((i * nRowsInChunk) + n) * 
										(nRowsInChunk * nRowChunks )) + 
									 ((j * nColsInChunk) + m) ;

						if (( m + nStep ) < nColsInChunk ) { 

						  m+=nStep;

						  /* Print a comma separator except for the first */
						  /* cell in chunk. 							  */

						  if ( 0 == outputInBinary ) { 

						  	if (firstInChunk) {
						    	firstInChunk = 0;
						  	} else {
						    	printf(",\n ");
						  	}

						  	printf(" {%d, %d} ",
									i * nRowsInChunk + n, 
									j * nColsInChunk + m
								);
						  } else {
					
							unsigned long int X = i * nRowsInChunk + n;
							unsigned long int Y = j * nColsInChunk + m;
							writeCoords ( X, Y );

						  }
							
						  if (nIsRandom) 
							print_random_attr_p( nTypeCnt, szTypesListStr, 
											   dbZProb, outputInBinary );
						  else
							print_det_attr( nTypeCnt, szTypesListStr, 
										    nCellNum, nCellMax,
                                            outputInBinary );

						  nStep = geomdev ( dbProb );
						  nCount++;

						  if (( m + nStep ) > nColsInChunk) { 
							nStep-=(nColsInChunk - m);
							break;
						  }

						} else {
							nStep-=(nColsInChunk-m);
							break;
						}
					}
				}
				if ( 0 == outputInBinary ) { 
					printf(" ]]");
				}
   			}
		}
		if ( 0 == outputInBinary ) { 
			printf("\n");
		}
	} else { 
		/*
		** Dense data.
		*/
		for(int i = 0;i < nRowChunks; i++ ) { 
			for(int j = 0;j < nColChunks; j++ ) { 
				nCount = 0;

				if ( 0 == outputInBinary ) { 
					if (i+j)
						printf(";\n[\n");
					else 
						printf("[\n");
				}

				for (int n = 0; n < nRowsInChunk; n++ ) { 

					if ( 0 == outputInBinary ) { 
						if (n)
							printf(",\n[ ");
						else 
							printf("[ ");
					}

					for (int m = 0; m < nColsInChunk; m++ ) { 

						if ( 0 == outputInBinary ) { 
							if (m)  { 
								printf(", "); 
							}
						}

#ifdef  _UNDEFINED 

printf("\n+=============================+\n");
printf("||  i (RowChunks)    =   %3d ||\n", i);
printf("||      RowsInChunk  =   %3d ||\n", nRowsInChunk);
printf("||  n (RowsInChunk)  =   %3d ||\n", n);
printf("||      nRowChunks   =   %3d ||\n", nRowChunks );
printf("||  j (ColChunks)    =   %3d ||\n", j); 
printf("||      nColsInChunk =   %3d ||\n", nColsInChunk); 
printf("||  m (nColsInChunk) =   %3d ||\n", m);
printf("||      nColChunks   =   %3d ||\n", nColChunks);
printf("+=============================+\n");

#endif 

						//
						// Tricky bit here .... 
						// 
						nCellNum = (((i * nRowsInChunk) + n) * 
						//				(nRowsInChunk * nRowChunks )) + 
						  				(nColsInChunk * nColChunks )) + 
									 ((j * nColsInChunk) + m) ;

						if ((1.0 == dbProb) || 
					        (dbProb > ((double)random() / (double)INT_MAX))) 
						{
							if ( 1 == outputInBinary ) { 
								unsigned long int X = i * nRowsInChunk + n;
								unsigned long int Y = j * nColsInChunk + m;
								writeCoords ( X, Y );
							}

							if (nIsRandom) 
								print_random_attr_p( nTypeCnt, szTypesListStr, 
												   dbZProb, outputInBinary );
							else {
								print_det_attr( nTypeCnt, szTypesListStr, 
											    nCellNum, nCellMax, outputInBinary);
							}
						} else { 
							if ( 0 == outputInBinary ) { 
								print_empty_attr();
							}
						}
						nCount++;
					}
					if ( 0 == outputInBinary ) { 
						printf("]");
					}
				}
				if ( 0 == outputInBinary ) { 
					printf("\n]");
				}
			}
		}
		if ( 0 == outputInBinary ) { 
			printf("\n");
		}
	}
}