def check_euler_angles(inputf): file1 = inputf grains1 = multigrainOutputParser.parseGrains(file1) ngrains1 = len(grains1) print "Parsed %s, found %d grains" % (file1, len(grains1)) unity = numpy.identity(3) print "Comparing Euler angles and U matrices. Making sure they match." for grain in grains1: angles = grain.geteulerangles() U = grain.getU() cphi1 = math.cos(math.radians(angles[0])) sphi1 = math.sin(math.radians(angles[0])) cPhi = math.cos(math.radians(angles[1])) sPhi = math.sin(math.radians(angles[1])) cphi2 = math.cos(math.radians(angles[2])) sphi2 = math.sin(math.radians(angles[2])) U2 = numpy.matrix([[ cphi1 * cphi2 - sphi1 * sphi2 * cPhi, -cphi1 * sphi2 - sphi1 * cphi2 * cPhi, sphi1 * sPhi ], [ sphi1 * cphi2 + cphi1 * sphi2 * cPhi, -sphi1 * sphi2 + cphi1 * cphi2 * cPhi, -cphi1 * sPhi ], [sphi2 * sPhi, cphi2 * sPhi, cPhi]]) C = U.dot(numpy.linalg.inv(U2)) if (not numpy.allclose(C, unity)): print "Problem with grain %s" % grain.getName() print C print "Done." return
def test(): # here = os.path.dirname(__file__) # logfile = os.path.join(sys.prefix, 'TIMEleSS', 'data', 'gve-62-3.log') logfile = pkg_resources.resource_filename(__name__, '../data/gve-62-3.log') gfffile = pkg_resources.resource_filename(__name__, '../data/fcc_10bckg_.gff') print ("Ok, we made it. We loaded the various files") print ("\nTest GrainSpotter parsing:") grains1 = multigrainOutputParser.parseGrains(logfile) print ("Parsed %s, read %d grains" % (logfile, len(grains1))) print ("\nTest GFF parsing:") grains2 = multigrainOutputParser.parseGrains(gfffile) print ("Parsed %s, read %d grains" % (gfffile, len(grains2)))
def extract_euler_angles(inputf, outputf): file1 = inputf grains1 = multigrainOutputParser.parseGrains(file1) ngrains1 = len(grains1) print "Parsed %s, found %d grains" % (file1, len(grains1)) f = open(outputf, "w+") for grain in grains1: angles = grain.geteulerangles() f.write("%.2f %.2f %.2f\n" % (angles[0], angles[1], angles[2])) f.close() print "Euler angles saved in %s" % (outputf) return
def grainSpotterClean(inputfile, outputfile): """ Cleans output from GrainSpotter indexings. In particular, removes grains with no assigned peaks that occur from time to time. Generates a new output file with no such grain. Parameters: inputfile - GrainSpotter log file outputfile - name of output file with bogus grains removed """ # Reading list of grains from all files grains = multigrainOutputParser.parseGrains(inputfile, False) print("Parsed %s, found %d grains" % (inputfile, len(grains))) multigrainOutputParser.saveGrainSpotter(outputfile, grains) print("Saved %d grains in %s" % (len(grains), outputfile))
def comparaison(file1, file2, crystal_system, cutoff, outputstem, verbose): """ Function designed to compare the orientations of 2 collections of grains. Usually used to compare an output file from GrainSpotter and that of a simulation with PolyXSim to make sure the indexing makes sense. - try to match grains between both - maybe more - crystal_system can be one of the following values 1: Triclinic 2: Monoclinic 3: Orthorhombic 4: Tetragonal 5: Trigonal 6: Hexagonal 7: Cubic Parameters: file1 - file with the first list of grains (used as a reference) file2 - file with the second list of grains crystal_system - see abover outputstem - stem for output file for the grain comparison cutoff - mis-orientation below which the two grains are considered identical, in degrees verbose - save all grain comparison into an output file rather than only matching or non matching grain """ # Prepare output files filename1 = "%s-%s" % (outputstem, "log.dat") logfile = open(filename1, 'w') filename2 = "%s-%s" % (outputstem, "matching-grains.dat") logmatching = open(filename2, 'w') filename3 = "%s-%s" % (outputstem, "erroneous-grains.dat") logerroneous = open(filename3, 'w') filename4 = "%s-%s" % (outputstem, "missing-grains.dat") logmissing = open(filename4, 'w') if (not verbose): print( "4 output files will be generated: \n- %s,\n- %s,\n- %s,\n- %s\n" % (filename1, filename2, filename3, filename4)) else: filename5 = "%s-%s" % (outputstem, "verbose.dat") logverbose = open(filename5, 'w') # Counting number of grains grains1 = multigrainOutputParser.parseGrains(file1) grains2 = multigrainOutputParser.parseGrains(file2) ngrains1 = len(grains1) ngrains2 = len(grains2) logit(logfile, "Parsed %s, found %d grains" % (file1, len(grains1))) logit(logfile, "Parsed %s, found %d grains" % (file2, len(grains2))) logit( logfile, "\nMisorientation below which the two grains are considered identical, in degrees: %.1f\n" % cutoff) # Check for doubles in list 1 logit(logfile, "Check for doubles in %s" % file1) grains1clean = removeDoubleGrains(grains1, crystal_system, cutoff, logfile) logit(logfile, "") # Check for doubles in list 2 logit(logfile, "Check for doubles in %s" % file2) grains2clean = removeDoubleGrains(grains2, crystal_system, cutoff, logfile) logit(logfile, "") # Loop in unique grains in list 1, trying to find pairs in list 2 goodGrains = [] # grains in list 2 that exist in list 1 erroneousGrains = [] # grains in list 2 that do not exist in list 1 grains1cleanFound = numpy.full((len(grains1clean), 1), False, dtype=bool) logit(logfile, "Trying to match grains between the 2 collections...") for i in range(0, len(grains2clean)): grainMatched = [] grain2 = grains2clean[i] U2 = grain2.getU() for j in range(0, len(grains1clean)): grain1 = grains1clean[j] U1 = grain1.getU() if (verbose): # We provide an output file all comparisons angle = minMisorientation(U1, U2, crystal_system) logverbose.write("Grain %s of %s\n" % (grain1.getName(), file1)) logverbose.write("\tcompared with grain %s of %s\n" % (grain2.getName(), file2)) logverbose.write("\tmisorientation: %.2f°\n" % (angle)) logverbose.write("U grain 1: \n" + numpy.array2string(U1) + "\n") logverbose.write("U grain 2: \n" + numpy.array2string(U2) + "\n") logverbose.write("\n\n") if (matchGrains(U1, U2, crystal_system, cutoff)): grainMatched.append(j) grains1cleanFound[j] = True if len(grainMatched) > 1: logit( logfile, "- Found more than 1 pair for grain %d. Something is wrong" % i) sys.exit(2) elif len(grainMatched) > 0: goodGrains.append(i) grain1 = grains1clean[grainMatched[0]] U1 = grain1.getU() angle = minMisorientation(U1, U2, crystal_system) logit( logfile, "- Grain %s of %s matches %s of %s with a misorientation of %.2f°" % (grain1.getName(), file1, grain2.getName(), file2, angle)) logmatching.write("Grain %s of %s\n" % (grain1.getName(), file1)) logmatching.write("\tmatches grain %s of %s\n" % (grain2.getName(), file2)) logmatching.write("\tmisorientation: %.2f°\n" % (angle)) logmatching.write("U grain 1: \n" + numpy.array2string(U1) + "\n") logmatching.write("U grain 2: \n" + numpy.array2string(U2) + "\n") logmatching.write("\n\n") else: erroneousGrains.append(i) logit(logfile, "- Grain %s of %s has no match" % (grain2.getName(), file2)) logerroneous.write("\nGrain %s of %s: no match\n" % (grain2.getName(), file2)) for j in range(0, len(grains1clean)): grain1 = grains1clean[j] U1 = grain1.getU() angle = minMisorientation(U1, U2, crystal_system) logerroneous.write("- Min angle with grain %s: %.2f°\n" % (grain1.getName(), angle)) logit(logfile, "End of run\n") for i in range(0, len(grains1clean)): if (not grains1cleanFound[i]): grain1 = grains1clean[i] logmissing.write("Grain %s of %s has no match\n" % (grain1.getName(), file1)) logit(logfile, "N. of grains in %s: %d" % (file1, ngrains1)) logit(logfile, "N. of unique grains in %s: %d" % (file1, len(grains1clean))) logit(logfile, "N. of grains in %s: %d" % (file2, ngrains2)) logit(logfile, "N. of unique grains in %s: %d" % (file2, len(grains2clean))) logit( logfile, "N. of unique grains found in both %s and %s: %d" % (file1, file2, len(goodGrains))) logit( logfile, "N. of unique grains found only in %s: %d" % (file2, len(erroneousGrains))) logit( logfile, "N. of unique grains found in %s but not in %s: %d" % (file1, file2, len(grains1clean) - len(goodGrains))) logit(logfile, "\nIndexing capability") logit( logfile, "- %.1f pc of %s grains indexed" % (100. * len(goodGrains) / len(grains1clean), file1)) logit( logfile, "- %.1f pc of %s grains not indexed" % (100. - 100. * len(goodGrains) / len(grains1clean), file1)) logit( logfile, "- %.1f pc of erroneous grains in %s" % (100. * len(erroneousGrains) / len(grains2clean), file2)) if (verbose): print( "\n5 output files were generated: \n- %s,\n- %s with the matching grains,\n- %s with erroneous grains,\n- %s with missing grains,\n- %s with verbose grain comparison \n" % (filename1, filename2, filename3, filename4, filename5)) else: print( "\n4 output files were generated: \n- %s,\n- %s with the matching grains,\n- %s with erroneous grains,\n- %s with missing grains\n" % (filename1, filename2, filename3, filename4)) logmatching.close() logfile.close() logerroneous.close() logmissing.close() if (verbose): logverbose.close()
def grainSpotterMerge(files, crystal_system, cutoff, outputstem): """ Function designed to merge output from multiple GrainSpotter indexing crystal_system can be one of the following values 1: Triclinic 2: Monoclinic 3: Orthorhombic 4: Tetragonal 5: Trigonal 6: Hexagonal 7: Cubic Parameters: files - list of GrainSpotter log files crystal_system - see above outputstem - stem for output file for the grain comparison cutoff - mis-orientation below which the two grains are considered identical, in degrees """ filename1 = "%s-%s" % (outputstem , "log.dat") logfile = open(filename1,'w') # Reading list of grains from all files grainLists = [] for filename in files: grains = multigrainOutputParser.parseGrains(filename) grainLists.append(grains) logit(logfile, "Parsed %s, found %d grains" % (filename, len(grains))) logit(logfile, "\nMisorientation below which the two grains are considered identical, in degrees: %.1f\n" % cutoff) # Looking for unique grains mergeGrains = [] for grains in grainLists: mergeGrains += grains logit(logfile, "Looking for unique grains") grainsUnique = grainComparison.removeDoubleGrains(mergeGrains, crystal_system, cutoff, logfile) logit(logfile, "") # Getting some stats for each for those grains logit(logfile, "Indexing statistics") nIndexed = [] for i in range(0,len(grainsUnique)): grain1 = grainsUnique[i] n = 0 for grain2 in mergeGrains: U1 = (grain1).getU() U2 = (grain2).getU() if (grainComparison.matchGrains(U1,U2,crystal_system,cutoff)): # We have a match. Keep the grain with the largest number of peaks n += 1 if (grain2.getNPeaks() > grain1.getNPeaks()): grainsUnique[i] = grain2 nIndexed.append(n) nn = grainComparison.unique(nIndexed) nn.sort(reverse=True) for i in nn: nGnTimes = sum(1 for j in nIndexed if i == j) logit(logfile,"- %d grains were indexed %d times" % (nGnTimes,i)) # Saving new files (in GrainSpotter format), based on the number of time each grain was indexed logit(logfile, "\nSaving unique grains") filename = ("%s-grains.log" % (outputstem)) multigrainOutputParser.saveGrainSpotter(filename,grainsUnique) logit(logfile,"- all %d unique grains saved in %s" % (len(grainsUnique), filename)) for i in nn: filename = ("%s-grains-%d.log" % (outputstem, i)) # Looking for grains that have been index i times indexlist = [j for j,x in enumerate(nIndexed) if x==i] # Save them tosave = [] for j in range(0,len(indexlist)): tosave.append(grainsUnique[j]) multigrainOutputParser.saveGrainSpotter(filename,tosave) logit(logfile,"- %d grains indexed %d times saved in %s" % (len(tosave),i, filename)) logfile.close()
def gs_indexing_statistics(logfile, gve, gsinputfile, wavelength): """ Checks a grainspotter indexing performance Send the final GrainSpotter log, the list of g-vectors, the GS input file (with the loosest conditions), and the wavelength """ nphases = len(logfile) grains = [] ngrains = [] gsinput = [] nindexed = [] totalngrains = 0 totalindexedpeaks = 0 i = 0 # Parsing grain spotter output in input files # Extracting grain information for thislog in logfile: grains.append(multigrainOutputParser.parseGrains(thislog)) print("Parsed %s, found %d grains" % (thislog, len(grains[i]))) print("Parsing grain spotter input file %s." % (gsinputfile[i])) # Load the grain spotter input file gsinput.append(multigrainOutputParser.parseGSInput(gsinputfile[i])) print("\nGrainSpotter results for phase %d" % i) print("\t%d grains indexed" % (len(grains[i]))) nindexed.append(0) ngrains.append(len(grains[i])) totalngrains += len(grains[i]) for grain in grains[i]: nindexed[i] += grain.getNPeaks() print("\t%d g-vectors indexed" % (nindexed[i])) totalindexedpeaks += nindexed[i] tt = 1.0 * nindexed[i] / ngrains[i] print("\t%.1f g-vectors per grain in average" % (tt)) i = i + 1 print("") print("Done parsing grain files.\n") # Extract peak list and ds ranges in which to look for peak # For each phase, the list of peaks is on top of the gve file # Then, need keep a record of the ds tolerance for the peak (which could different for each phase) peakssample = [] peaksgve = [None] * nphases idlist = [None] * nphases for i in range(0, nphases): [peaksgve[i], idlist[i], header] = multigrainOutputParser.parseGVE(gve[i]) print( "Parsing header from GVE files %s to extract predicted sample peaks for phase %i" % (gve[i], i)) tttol = gsinput[i]["sigma_tth"] * gsinput[i]["nsigmas"] recordpeaks = False for line in header.split("\n"): if ((line.strip() == "# gx gy gz xc yc ds eta omega spot3d_id xl yl zl" )): recordpeaks = False # We reached the end of the header... if recordpeaks: try: tt = line.split() ds = float(tt[0]) h = int(tt[1]) k = int(tt[2]) l = int(tt[3]) tt = 2. * numpy.degrees(numpy.arcsin(wavelength * ds / 2.)) dsmin = 2. * numpy.sin(numpy.radians( (tt - tttol) / 2.)) / (wavelength) dsmax = 2. * numpy.sin(numpy.radians( (tt + tttol) / 2.)) / (wavelength) except ValueError: print( "Conversion error when reading predicted sample peaks from %s." % (gve[i])) print("Was trying to convert %s to ds, h, k, and l" % (line)) sys.exit(1) peakssample.append([ds, h, k, l, tt, dsmin, dsmax, tttol]) if ((line.strip() == "# ds h k l")): recordpeaks = True print( "\nRead theoretical peak positions in 2theta for all phases.\nI have a list of %d potential peaks for all %d phases.\n" % (len(peakssample), nphases)) # Merging peaks from GVE files, removing doubles allgves = peaksgve[0] allPeakIds = idlist[0] for i in range(1, nphases): missinggveID = set(idlist[i]).symmetric_difference(set(allPeakIds)) for peakid in missinggveID: ID_idlist = (idlist[i]).index(peakid) allPeakIds.append(peakid) allgves.append(peaksgve[i][ID_idlist]) print( "Merged unique g-vectors of all %d gve files. I now have %d experimental g-vectors." % (nphases, len(allgves))) # Loop on all experimental g-vectors # Are they in one of the 2 theta, omega, and eta ranges defined in grain spotter? # Need to check for all phases ds = [] eta = [] omega = [] keepPeak = [False] * len(allgves) for i in range(1, nphases): # Loop on phase gsinput[i]["dsranges"] = [] for tthrange in gsinput[i][ "tthranges"]: # Convert 2theta range to ds range for easier comparison ds0 = 2. * numpy.sin(numpy.radians( tthrange[0] / 2.)) / (wavelength) ds1 = 2. * numpy.sin(numpy.radians( tthrange[1] / 2.)) / (wavelength) (gsinput[i]["dsranges"]).append([ds0, ds1]) # Loop on peaks. If the peak is within the range, we keep it for later for j in range(0, len(allgves)): peak = allgves[j] thisds = float(peak['ds']) thiseta = normalizedAngle360(float( peak['eta'])) # In GrainSpotter, eta is in [0;360] thisomega = normalizedAngle180(float( peak['omega'])) # In GrainSpotter, omega is in [-180;180] test1 = 0 test2 = 0 test3 = 0 for dsrange in gsinput[i]["dsranges"]: if ((thisds >= dsrange[0]) and (thisds <= dsrange[1])): test1 = 1 for etarange in gsinput[i]["etaranges"]: if ((thiseta >= etarange[0]) and (thiseta <= etarange[1])): test2 = 1 #else: # print "Not for eta %.1f < %.1f < %.1f" % (etarange[0],thiseta,etarange[1]) for omegarange in gsinput[i]["omegaranges"]: if ((thisomega >= omegarange[0]) and (thisomega <= omegarange[1])): test3 = 1 #else: # print "Not for omega %.1f < %.1f < %.1f" % (omegarange[0],thisomega,omegarange[1]) if ( test1 * test2 * test3 == 1 ): # The peak is within the range of ttheta, eta, and omega for phase i. It could have been indexed. keepPeak[j] = True for j in range(0, len(allgves)): if (keepPeak[j]): peak = allgves[j] ds.append(float(peak['ds'])) eta.append(float(peak['eta'])) omega.append(float(peak['omega'])) print( "%d g-vectors within eta, omega, and 2theta ranges and could have been indexed." % (len(ds))) # Counting peak, within 2 theta range, and that can be assigned to the sample nassigned = 0 for thisds in ds: append = 0 for i in range(0, len(peakssample)): if ((thisds <= peakssample[i][6]) and (thisds >= peakssample[i][5])): append = 1 nassigned += append print( "%d g-vectors assigned to one of the sample peaks within these ranges." % (nassigned)) print("\nGlobal indexing performance") print( "\tOut of %d possible g-vectors, %d have been assigned to %d grains" % (nassigned, totalindexedpeaks, totalngrains)) tt = nassigned - totalindexedpeaks print("\t%d remaining g-vectors" % (tt)) tt = 100. * totalindexedpeaks / nassigned print("\t%.1f percents of g-vectors indexed" % (tt)) print() return
def test_grains(grainfile,gvefile,wavelength): """ Check a GrainSpotter log file against a GVE file This can be used to make sure that this exact GVE file was actually used to index the grains """ grains = multigrainOutputParser.parseGrains(grainfile) print ("Parsed %s, found %d grains" % (grainfile, len(grains))) # Load .gve file from ImageD11 : [peaksgve,idlist,header] = multigrainOutputParser.parseGVE(gvefile) # Try to see if all peaks in the indexed grains are in the gve print ("Making sure all indexed peak ID's are in the GVE file...") npeakstotal = 0 npeakserror = 0 for grain in grains : peaks = grain.peaks for indexedPeak in peaks : npeakstotal += 1 try: ID_grains = indexedPeak.getPeakID() ID_idlist = idlist.index(ID_grains) ID_gve = peaksgve[ID_idlist] except ValueError: print ("Peak %d of grain %s not found" % (ID_grains, grain.getName() )) npeakserror += 1 if (npeakserror > 10): print ("Too many errors, I stop here") return print ("I was looking for %d peaks from %d grains and got %d errors" % (npeakstotal, len(grains), npeakserror)) if (npeakserror > 0): print ("%s and %s do not seem to match" % (grainfile, gvefile)) return print ("All peaks in the grain file are in the GVE file. Now, looking for 2theta, eta, omega to see if they match...") for grain in grains : peaks = grain.peaks for indexedPeak in peaks : npeakstotal += 1 ID_grains = indexedPeak.getPeakID() omegaG = normalizedAngle(indexedPeak.getOmegaMeasured()) etaG = normalizedAngle(indexedPeak.getEtaMeasured()) tthetaG = indexedPeak.getTThetaMeasured() dsG = 2.*numpy.sin(numpy.radians(tthetaG/2.))/(wavelength) ID_idlist = idlist.index(ID_grains) #print peaksgve[ID_idlist] #return dsPeak = float(peaksgve[ID_idlist]['ds']) etaPeak = normalizedAngle(float(peaksgve[ID_idlist]['eta'])) omegaPeak = normalizedAngle(float(peaksgve[ID_idlist]['omega'])) if ((abs(etaG-etaPeak) > 0.01) or (abs(omegaPeak-omegaG) > 0.01) or (abs(dsG-dsPeak) > 0.001)): print ("Problem with peak %d of grain %s not found" % (ID_grains, grain.getName() )) print ("Expected: eta = %.2f , omega = %.2f, ds = %.4f" % (etaG, omegaG, dsG)) print ("Found: eta = %.2f , omega = %.2f, ds = %.4f" % (etaPeak, omegaPeak, dsPeak)) print ("Differences: eta = %.4f , omega = %.4f, ds = %.6f" % (abs(etaPeak-etaG), abs(omegaPeak-omegaG), abs(dsG-dsPeak))) npeakserror += 1 if (npeakserror > 10): print ("Too many errors, I stop here") return if (npeakserror > 0): print ("%s and %s do not seem to match" % (grainfile, gvefile)) return print ("All peaks in the grain file are in the GVE file and angles fully match.") return
def gs_indexing_statistics(logfile, gve, gsinput, wavelength): """ Checks a grainspotter indexing performance Send the final GrainSpotter log, the list of g-vectors, the GS input file (with the loosest conditions), and the wavelength """ grains = multigrainOutputParser.parseGrains(logfile) print "Parsed %s, found %d grains" % (logfile, len(grains)) # Load .gve file from ImageD11 : [peaksgve,idlist,header] = multigrainOutputParser.parseGVE(gve) # Extracting list of g-vectors from the header peakssample = [] recordpeaks = False #print header for line in header.split("\n"): if ((line.strip() == "# gx gy gz xc yc ds eta omega spot3d_id xl yl zl")): recordpeaks = False if recordpeaks: tt = line.split() ds = float(tt[0]) h = int(tt[1]) k = int(tt[2]) l = int(tt[3]) peakssample.append([ds,h,k,l]) #print h, k, l if ((line.strip() == "# ds h k l")): recordpeaks = True # Load the grain spotter input file gsinput = multigrainOutputParser.parseGSInput(gsinput) # Try to see if all g-vectors in the indexed grains are in the gve nindexed = 0 ngrains = len(grains) for grain in grains : nindexed += grain.getNPeaks() print "\nGrainSpotter results" print "\t%d grains indexed" % (len(grains)) print "\t%d g-vectors indexed" % (nindexed) tt = 1.0*nindexed/ngrains print "\t%.1f g-vectors per grain in average" % (tt) # Matching conditions in angle ranges ds = [] eta = [] omega = [] gsinput["dsranges"] = [] for tthrange in gsinput["tthranges"]: ds0 = 2.*numpy.sin(numpy.radians(tthrange[0]/2.))/(wavelength) ds1 = 2.*numpy.sin(numpy.radians(tthrange[1]/2.))/(wavelength) gsinput["dsranges"].append([ds0,ds1]) #print gsinput for peak in peaksgve: thisds = float(peak['ds']) thiseta = normalizedAngle360(float(peak['eta'])) # In GrainSpotter, eta is in [0;360] thisomega = normalizedAngle180(float(peak['omega'])) # In GrainSpotter, omega is in [-180;180] test1 = 0 test2 = 0 test3 = 0 for dsrange in gsinput["dsranges"]: if ((thisds >= dsrange[0]) and (thisds <= dsrange[1])): test1 = 1 for etarange in gsinput["etaranges"]: if ((thiseta >= etarange[0]) and (thiseta <= etarange[1])): test2 = 1 #else: # print "Not for eta %.1f < %.1f < %.1f" % (etarange[0],thiseta,etarange[1]) for omegarange in gsinput["omegaranges"]: if ((thisomega >= omegarange[0]) and (thisomega <= omegarange[1])): test3 = 1 #else: # print "Not for omega %.1f < %.1f < %.1f" % (omegarange[0],thisomega,omegarange[1]) if (test1*test2*test3 == 1): ds.append(float(peak['ds'])) eta.append(float(peak['eta'])) omega.append(float(peak['omega'])) print "\nPeaks" print "\t%d g-vectors in GVE file" % (len(peaksgve)) print "\t%d g-vectors within eta, omega, and 2theta ranges" % (len(ds)) # Counting peak, within 2 theta range, and that can be assigned to the sample tttol = gsinput["sigma_tth"]*gsinput["nsigmas"] dsmin = [] dsmax = [] #print tttol for samplepeak in peakssample: thisds = samplepeak[0] #print thisds tt = 2.*numpy.degrees(numpy.arcsin(wavelength*thisds/2.)) #print 2.*numpy.sin(numpy.radians((tt-tttol)/2.))/(wavelength) #print 2.*numpy.sin(numpy.radians((tt+tttol)/2.))/(wavelength) dsmin.append(2.*numpy.sin(numpy.radians((tt-tttol)/2.))/(wavelength)) dsmax.append(2.*numpy.sin(numpy.radians((tt+tttol)/2.))/(wavelength)) nassigned = 0 for thisds in ds: append = 0 for i in range(0,len(dsmin)): if ((thisds <= dsmax[i]) and (thisds >= dsmin[i])): append = 1 nassigned += append print "\t%d g-vectors assigned to sample within these ranges" % (nassigned) print "\nIndexing performance" print "\tOut of %d possible g-vectors, %d have been assigned to %d grains" % (nassigned, nindexed, len(grains)) tt = nassigned-nindexed print "\t%d remaining g-vectors" % (tt) tt = 100.*nindexed/nassigned print "\t%.1f percents of g-vectors indexed" % (tt) print return
def comparaison(file1, file2, crystal_system, cutoff, outputstem): """ Function designed to compare the orientations of 2 collections of grains. Usually used to compare an output file from GrainSpotter and that of a simulation with PolyXSim to make sure the indexing makes sense. - try to match grains between both - maybe more - crystal_system can be one of the following values 1: Triclinic 2: Monoclinic 3: Orthorhombic 4: Tetragonal 5: Trigonal 6: Hexagonal 7: Cubic Parameters: file1 - file with the first list of grains (used as a reference) file2 - file with the second list of grains crystal_system - see abover outputstem - stem for output file for the grain comparison cutoff - mis-orientation below which the two grains are considered identical, in degrees """ # Prepare output files filename1 = "%s-%s" % (outputstem, "log.dat") logfile = open(filename1, 'w') print("1 output files will be generated: \n- %s\n" % (filename1)) # Counting number of grains grains1 = multigrainOutputParser.parseGrains(file1) grains2 = multigrainOutputParser.parseGrains(file2) ngrains1 = len(grains1) ngrains2 = len(grains2) logit(logfile, "Parsed %s, found %d grains" % (file1, len(grains1))) logit(logfile, "Parsed %s, found %d grains" % (file2, len(grains2))) logit( logfile, "\nMisorientation below which the two grains are considered identical, in degrees: %.1f\n" % cutoff) # Check for doubles in list 1 logit(logfile, "Check for doubles in %s" % file1) grains1clean = removeDoubleGrains(grains1, crystal_system, cutoff, logfile) logit(logfile, "") # Check for doubles in list 2 logit(logfile, "Check for doubles in %s" % file2) grains2clean = removeDoubleGrains(grains2, crystal_system, cutoff, logfile) logit(logfile, "") # Will hold grains that match a peak peaksInGrains = {} # Loop in unique grains in list 1, trying to grains in list 2 that share the same peaks for i in range(0, len(grains1clean)): grain1 = grains1clean[i] grains1GVEID = grain1.getPeaksGVEID() for j in range(0, len(grains2clean)): grain2 = grains2clean[j] grains2GVEID = grain2.getPeaksGVEID() matches = set(grains1GVEID).intersection(grains2GVEID) if (len(matches) > 0): logit( logfile, "- Grain %s of %s shares %d peaks with %s of %s" % (grain1.getName(), file1, len(matches), grain2.getName(), file2)) logit(logfile, "Matching peaks (GVE ID): " + str(list(matches))) for peak in matches: try: grains = peaksInGrains[peak] grains.append(grain1.getName() + " in " + file1) grains.append(grain2.getName() + " in " + file2) peaksInGrains[peak] = grains except KeyError: # Key is not present peaksInGrains[peak] = [ grain1.getName() + " in " + file1, grain2.getName() + " in " + file2 ] logit(logfile, "\nPeaks information\n") for peak in peaksInGrains: logit( logfile, "- peak %s is seen in %d grains: " % (peak, len(peaksInGrains[peak])) + str(peaksInGrains[peak])) return