Utilities in libcfshr

The utility functions listed here are defined in various separate files. They are declared in cfsemshare.h, which includes mrcslice.h and is included by b3dutil.h.

Function to Test for Point Inside Boundary


int InsideContour(float *ptX, float *ptY, int np, float x, float y)
int insidecontour(float *ptX, float *ptY, int *np, float *x, float *y)

Function for Finding Convex Boundary


void convexBound(float *sx, float *syin, int npnts, float fracomit, float pad, float *bx, float *by, int *nvert, float *xcen, float *ycen, int maxverts)
void convexbound(float *sx, float *syin, int *npnts, float *fracomit, float *pad, float *bx, float *by, int *nvert, float *xcen, float *ycen, int *maxverts)

Function for Sorting Points onto Two Surfaces


int setSurfSortParam(int index, float value)
int setsurfsortparam(int *index, float *value)
int surfaceSort(float *xyz, int numPts, int markersInGroup, int *group)
int surfacesort(float *xyz, int *numPts, int *markersInGroup, int *group)
Algorithm and Parameters for surfaceSort

Function for Parsing Lists


int *parselist(const char *line, int *nlist)
int parselistfw(const char *line, int *list, int *nlist, int *limlist, int linelen)

Functions for Writing Lists


int writeList(int *list, int numList, int lineLen)
int writelist(int *list, int *numList, int *lineLen)
void wrlist(int *list, int *numList)
char *listToString(int *list, int numList)

Histogram Functions


void kernelHistogram(float *values, int numVals, float *bins, int numBins, float firstVal, float lastVal, float h, int verbose)
void kernelhistogram(float *values, int *numVals, float *bins, int *numBins, float *firstVal, float *lastVal, float *h, int *verbose)
int scanHistogram(float *bins, int numBins, float firstVal, float lastVal, float scanBot, float scanTop, int findPeaks, float *dip, float *peakBelow, float *peakAbove)
int scanhistogram(float *bins, int *numBins, float *firstVal, float *lastVal, float *scanBot, float *scanTop, int *findPeaks, float *dip, float *peakBelow, float *peakAbove)
int findHistogramDip(float *values, int numVals, int minGuess, float *bins, int numBins, float firstVal, float lastVal, float *histDip, float *peakBelow, float *peakAbove, int verbose)
int findhistogramdip(float *values, int *numVals, int *minGuess, float *bins, int *numBins, float *firstVal, float *lastVal, float *histDip, float *peakBelow, float *peakAbove, int *verbose)

Functions for Analyzing Gold Beads


void makeModelBead(int boxSize, float beadSize, float *array)
void makemodelbead(int *boxSize, float *beadSize, float *array)
double beadIntegral(float *array, int nxdim, int nx, int ny, float rCenter, float rInner, float rOuter, float xcen, float ycen, float *cenmean, float *annmean, float *temp, float annPct, float *median)

Functions for Image Statistics by Sampling


int sampleMinMaxMeanSD(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean, float *sd, float *amin, float *amax)
int sampleMeanOnly(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean)
int sampleMeanSD(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean, float *sd)
int sampleMinMaxMean(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean, float *amin, float *amax)
int sampleminmaxmeansd(float *image, int *nx, int *ny, float *sample, int *ixStart, int *iyStart, int *nxUse, int *nyUse, int which, float *mean, float *sd, float *dmin, float *dmax)
int samplemeansd(float *image, int *nx, int *ny, float *sample, int *ixStart, int *iyStart, int *nxUse, int *nyUse, float *mean, float *sd, float *dmin, float *dmax)
int typeForSampleMean(int mrcMode)
int typeforsamplemean(int *mrcMode)
int getSampleOfArray(void *image, int mode, int nx, int ny, float sampleFrac, int ixStart, int iyStart, int nxUse, int nyUse, float fillToExclude, float *samples, int maxSamples, int *numSamples)
int percentileStretch(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float pctLo, float pctHi, float *scaleLo, float *scaleHi)

Functions for Measuring Volume Mean/SD at Multiple Binnings


int multiBinSetup(int binning[][3], int boxSize[][3], int boxSpacing[][3], int numScales, int startCoord[3], int endCoord[3], int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds)
int multibinsetup(int binning[][3], int boxSize[][3], int boxSpacing[][3], int *numScales, int *startCoord, int *endCoord, int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds)
int multiBinStats(int binning[][3], int boxSize[][3], int boxSpacing[][3], int numScales, int startCoord[3], int endCoord[3], int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds, float *buffer, float *means, float *SDs, int *funcData, int (*getSliceFunc)(int *, int *, float *))
int multibinstats(int binning[][3], int boxSize[][3], int boxSpacing[][3], int *numScales, int *startCoord, int *endCoord, int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds, float *buffer, float *means, float *SDs, int *funcData, int (*getSliceFunc)(int *, int *, float *))
void makeStandardDevMap(float *array, int nxDim, int ixStart, int ixEnd, int iyStart, int iyEnd, int binning, int boxSize, float *sdArr, float *sumArr, float *sqrArr, int *xOffset, int *yOffset)

Functions for Working with Montage Piece Lists


int checkPieceList(int *pclist, int stride, int npclist, int redfac, int nframe, int *minpiece, int *npieces, int *noverlap)
void checklist(int *pclist, int *npclist, int *redfac, int *nframe, int *minpiece, int *npieces, int *noverlap)
void adjustPieceOverlap(int *pclist, int stride, int npclist, int nframe, int minpiece, int noverlap, int newOverlap)
void adjustpieceoverlap(int *pclist, int *npclist, int *nframe, int *minpiece, int *noverlap, int *newOverlap)
void fillListOfPieceZ(int *izPcList, int nPcList, int *listZ, int *numListZ)
int readPieceList(const char *pieceFile, int *ixPcList, int *iyPcList, int *izPcList, int *nPcList, int maxPieces)

Functions for Finding Alignments of Montage Pieces


void montXCBasicSizes(int ixy, int nbin, int indentXC, int *nxyPiece, int *nxyOverlap, float aspectMax, float extraWidth, float padFrac, int niceLimit, int *indentUse, int *nxyBox, int *numExtra, int *nxPad, int *nyPad, int *maxLongShift)
void montxcbasicsizes(int *ixy, int *nbin, int *indentXC, int *nxyPiece, int *nxyOverlap, float *aspectMax, float *extraWidth, float *padFrac, int *niceLimit, int *indentUse, int *nxyBox, int *numExtra, int *nxPad, int *nyPad, int *maxLongShift)
void montXCIndsAndCTF(int ixy, int *nxyPiece, int *nxyOverlap, int *nxyBox, int nbin, int indentUse, int *numExtra, int nxPad, int nyPad, int numSmooth, float sigma1, float sigma2, float radius1, float radius2, int evalCCC, int *ind0Lower, int *ind1Lower, int *ind0Upper, int *ind1Upper, int *nxSmooth, int *nySmooth, float *ctf, float *delta)
void montxcindsandctf(int *ixy, int *nxyPiece, int *nxyOverlap, int *nxyBox, int *nbin, int *indentUse, int *numExtra, int *nxPad, int *nyPad, int *numSmooth, float *sigma1, float *sigma2, float *radius1, float *radius2, int *evalCCC, int *ind0Lower, int *ind1Lower, int *ind0Upper, int *ind1Upper, int *nxSmooth, int *nySmooth, float *ctf, float *delta)
int montXCFindBinning(int maxBin, int targetSize, int indentXC, int *nxyPiece, int *nxyOverlap, float aspectMax, float extraWidth, float padFrac, int niceLimit, int *numPaddedPix, int *numBoxedPix)
int montxcfindbinning(int *maxBin, int *targetSize, int *indentXC, int *nxyPiece, int *nxyOverlap, float *aspectMax, float *extraWidth, float *padFrac, int *niceLimit, int *numPaddedPix, int *numBoxedPix)
int montXCFindBinning2(int maxBin, int targetSize, int indentXC, int ixy, int *nxyPiece, int *nxyOverlap, int *expectedShift, float aspectMax, float extraWidth, float padFrac, int niceLimit, int *numPaddedPix, int *numBoxedPix)
int montxcfindbinning2(int *maxBin, int *targetSize, int *indentXC, int *ixy, int *nxyPiece, int *nxyOverlap, int *expectedShift, float *aspectMax, float *extraWidth, float *padFrac, int *niceLimit, int *numPaddedPix, int *numBoxedPix)
void montXCorrEdge(float *lowerIn, float *upperIn, int *nxyBox, int *nxyPiece, int *nxyOverlap, int nxSmooth, int nySmooth, int nxPad, int nyPad, float *lowerPad, float *upperPad, float *lowerCopy, int numXcorrPeaks, int legacy, float *ctf, float delta, int *inExtra, int nbin, int ixy, int maxLongShift, int weightCCC, float *xDisplace, float *yDisplace, float *CCC, void (*twoDfft)(float *, int *, int *, int *), void (*dumpEdge)(float *, int *, int *, int *, int *, int *), char *debugStr, int debugLen, int debugLevel)
void montxcorredge(float *lowerIn, float *upperIn, int *nxyBox, int *nxyPiece, int *nxyOverlap, int *nxSmooth, int *nySmooth, int *nxPad, int *nyPad, float *lowerPad, float *upperPad, float *lowerCopy, int *numXcorrPeaks, int *legacy, float *ctf, float *delta, int *numExtra, int *nbin, int *ixy, int *maxLongShift, int *weightCCC, float *xDisplace, float *yDisplace, float *CCC, void (*twoDfft)(float *, int *, int *, int *), void (*dumpEdge)(float *, int *, int *, int *, int *, int *), int *debugLevel)
void montxcorrgetmaxes(int *maxPeak, int *maxLines)
void montXCSetDistWeightHalfFall(float *inVal)
double montXCGetLastTrimmedMaxSD()
void montXCGetLastRunnersUp(float *disps, int maxPairs)
void rowOfThreeCorrs(float *array, float *brray, int nxDim, int ix0, int ix1, int iy0, int iy1, int delX, int delY, float *aWeights, float *bWeights, int nxWgt, int binning, int wgtXoffset, int wgtYoffset, float *corr1, float *corr2, float *corr3, double *sumArr1, double *sumArr2, double *sumArr3)
void columnOfThreeCorrs(float *array, float *brray, int nxDim, int ix0, int ix1, int iy0, int iy1, int delX, int delY, float *aWeights, float *bWeights, int nxWgt, int binning, int wgtXoffset, int wgtYoffset, float *corr1, float *corr2, float *corr3, double *sumArr1, double *sumArr2, double *sumArr3)
void montXCFindBestCorr(float *array, float *brray, int nxDim, int nx, int ny, int nxTrim, int nyTrim, int ixStart, int ixEnd, int iyStart, int iyEnd, float *delX, float *delY, float *corr, float maxDist, float *aWeights, float *bWeights, int nxWgt, int binning, int wgtXoffset, int wgtYoffset, float threshCCC, double *bestSumArr)
void montBigSearch(float *array, float *brray, int nx, int ny, int ixBox0, int iyBox0,int ixBox1, int iyBox1, float *dxMin, float *dyMin, float *sdMin, float *ddenMin, int numIter, int limStep)
void montbigsearch(float *array, float *brray, int *nx, int *ny, int *ixBox0, int *iyBox0,int *ixBox1, int *iyBox1, float *dxMin, float *dyMin, float *sdMin, float *ddenMin, int *numIter, int *limStep)
void montSdCalc(float *array, float *brray, int nx, int ny, int ixBox0, int iyBox0, int ixBox1, int iyBox1, float dx, float dy, float *sd, float *dden)
void montsdcalc(float *array, float *brray, int *nx, int *ny, int *ixBox0, int *iyBox0, int *ixBox1, int *iyBox1, float *dx, float *dy, float *sd, float *dden)
int findPieceShifts(int *ivarpc, int nvar, int *indvar, int *ixpclist, int *iypclist, float *dxedge, float *dyedge, int idir, int *pieceLower, int *pieceUpper, int *ifskipEdge, int edgeStep, float *dxyvar, int varStep, int *edgeLower, int *edgeUpper, int pcStep, float *work, int fort, int leaveInd, int skipCrit, float robustCrit, float critMaxMove, float critMoveDiff, int maxIter, int numAvgForTest, int intervalForTest, int *numIter, float *wErrMean, float *wErrMax)
int findPieceScalings(int *ivarpc, int nvar, int *indvar, int *ixpclist, int *iypclist, float *ddenEdge, int idir, int *pieceLower, int *pieceUpper, int *ifskipEdge, int edgeStep, float *ddenVar, int *edgeLower, int *edgeUpper, int pcStep, float *work, int fort, int leaveInd, int skipCrit, float critMaxMove, float critMoveDiff, int maxIter, int numAvgForTest, int intervalForTest, int *numIter, float *wErrMean, float *wErrMax)
int pickAlternativeShifts(int *ivarpc, int nvar, int *indvar, float *dxedge, float *dyedge, int *pieceLower, int *pieceUpper, int *ifskipEdge, int edgeStep, int *edgeLower, int *edgeUpper, int pcStep, int fort, float *altDxys, int numAlts, int altIxy, float errThresh, float reduceFac, float newThresh, int *fixedEdges, int *numFixed)

Function for Computing a Scaled, Reduced Power Spectrum


int spectrumScaled(void *image, int type, int nx, int ny, void *spectrum, int padSize, int finalSize, int bkgdGray, float truncDiam, int filtType, void (*twoDfft)(float *, int *, int *, int *))
void makeAmplitudeSpectrum(float *fftArray, float *spectrum, int padSize, int outXdim)

Function for fast n*90 rotation/flip operation


int rotateFlipImage(void *array, int mode, int nx, int ny, int operation, int leftHanded, int invertAfter, int invertCon, void *brray, int *nxout, int *nyout, int numThreads)
int rotateflipimage(float *array, int *nx, int *ny, int *operation, float *brray, int *nxout, int *nyout, int *numThreads)

Function for Reading Lines of Values


int readLinesForValues(FILE *fp, int *numToGetP, int valSize, char *line, int maxLine, int flags, const char *types, ...)
void exitFromValueReadError(int ierr, const char *descrip)

Functions for Getting Tilt Angles


void getTiltAngles(int *numViews, float *tilt, int limTilt)
void readTiltFile(int *numViews, char *filename, float *tilt, int limTilt)

Color Map Functions


int *cmapStandardRamp()
int *cmapInvertedRamp()
int cmapConvertRamp(int *rampData, unsigned char table[3][256])
int cmapReadConvert(char *filename, unsigned char table[3][256])
Standard color ramps

Function to Test for Point Inside Boundary

int InsideContour(float *ptX, float *ptY, int np, float x, float y)

Returns 1 if the point x, y is inside or on the polygon (contour) whose vertices are in ptX, ptY, where np is the number of points, otherwise returns 0.

int insidecontour(float *ptX, float *ptY, int *np, float *x, float *y)

Fortran wrapper to InsideContour .  But it is more convenient to call
   logical function inside(ptX, ptY, np, x, y)

Function for Finding Convex Boundary

void convexBound(float *sx, float *syin, int npnts, float fracomit, float pad, float *bx, float *by, int *nvert, float *xcen, float *ycen, int maxverts)

Finds the smallest convex boundary around an arbitrary set of points in sx, sy.  npnts is the total number of points. If fracomit is nonzero, it omits that fraction of points from consideration completely, choosing the points that are farthest from the centroid of all the points.  (If fracomit is negative, the Y coordinates of the points will be temporarily scaled to have the same standard deviation as the X range in order to determine the farthest points; it then eliminates -fracomit points.) It returns the centroid of the points under consideration in xcen, ycen.  It returns the set of boundary points in bx, by and the number of points in nvert.  The size of bx and by is specified by maxverts.  If pad is nonzero, it makes the boundary points be that distance away from the outermost sx, sy points. It uses Graham's scan algorithm.  nvert is returned with -1 for an error allocating temporary arrays, or -2 for the boundary arrays not large enough.

void convexbound(float *sx, float *syin, int *npnts, float *fracomit, float *pad, float *bx, float *by, int *nvert, float *xcen, float *ycen, int *maxverts)

Fortran wrapper for convexBound

Function for Sorting Points onto Two Surfaces

int setSurfSortParam(int index, float value)

Sets one parameter for surfaceSort .

int setsurfsortparam(int *index, float *value)

Fortran wrapper for setSurfSortParam

int surfaceSort(float *xyz, int numPts, int markersInGroup, int *group)

Sorts a set of points in 3D onto two surfaces.  The X, Y, and Z coordinates of the numPts points are packed sequentially into the array xyz.  If markersInGroup is nonzero, then the group array should be passed in with 0 for points eligible to be included in the pairs of points that are used to initiate a cluster, or with a -1 for points that should not be used to initiate clusters.  The surface numbers, 1 for the bottom one and 2 for the top one, are returned in group.  The return value is 1 for a memory allocation error.

int surfacesort(float *xyz, int *numPts, int *markersInGroup, int *group)

Fortran wrapper for surfaceSort, where xyz is dimensioned to (3,*)

Algorithm and Parameters for surfaceSort

This routine works as follows:
First it fits a plane to all of the points and rotates the points to make that plane level.  Analysis proceeds with rotated positions.
For rapid access to neighboring points, it sets up a grid of squares (at sGridSpacing) and list of delta values to grid positions in successively wider rings around one grid square.  Then it makes lists of points within each grid square.
For each point (not marked as an outlier by values of -1 in the group array) it then searches for the neighboring point at the steepest angle with respect to it, looking at up to sMaxAngleNeigh neighbors.
Duplicate pairs are allowed to form, and are eliminated after sorting.
The points are sorted by steepest angle, and then it determines a set of pairs to use for building clusters, as controlled by parameters sSteepestRatio, sNumMinForAmax, sAngleMax, sNumMinForArelax, and sAngleRelax.
Given this set of pairs, it then makes a list of the separation in Z between each pair and analyzes for MAD-Median outliers with criterion sOutlierCrit.  These outliers are eliminated from cluster formation, as are the ones identified by the caller. Pairs are always considered in order from the steepest angle downward.  To build a cluster, it starts with the next point that hasn't been added to a cluster yet, putting it and its pair on a list of cluster points to check.  Each point on the cluster list is checked for whether it occurs in a pair at a steep angle, and if so its mate is then added to the opposite group.
For each cluster, a central position and an average delta Z are computed.
Finally, it searches in progressively bigger rings around the clusters for grid squares where there are unassigned points.  When it finds an unassigned point, it collects the nearest assigned points in the neighborhood up to sMaxNumFit or up to a distance of sMaxFitDist.  If this includes points from both surfaces and there are at least sBiplaneMinFit points, it fits a pair of planes to all points; otherwise it fits a single plane to just the points from one surface if there are at least sPlaneMinFit points for this; otherwise it simply gets a mean of Z positions on the top and bottom if possible.  One way or another this gives an estimate of the top and bottom Z position at the unassigned point, and it assigns the point based on which Z it is closer to.  In fact, this process is done in two rounds, and on the first round assignment is deferred if the disparity between the point and estimated surface Z values as a percentage of the Z separation exceeds sMaxRound1Dist.

The numbers in the comments below are index values for setSurfSortParam

/* Spacing of squares for sorting points and accessing rings of points */
static float sGridSpacing = 50.; /* 0 */
/* Maximum neighbors to evaluate for finding neighbor with steepest angle */
static int sMaxAngleNeigh = 50;  /* 1 */
/* Use pairs with angle more than this fraction of very steepest angle */
static float sSteepestRatio = 0.5f; /* 2 */
/* If there are fewer than this number of pairs, take pairs down to sAngleMax */
static int sNumMinForAmax = 10;  /* 3 */
/* Angle to go down to if sSteepestRatio doesn't give enough pairs */
static float sAngleMax = 20.;    /* 4 */
/* If fewer than this number of pairs, take pairs down to sAngleRelax */
static int sNumMinForArelax = 3; /* 5 */
/* Angle to go down to if sAngleMax doesn't give enough pairs */
static float sAngleRelax = 5.;   /* 6 */
/* Criterion for MAD-Median outlier elimination based on delta Z of a pair */
static float sOutlierCrit = 3.;  /* 7 */
/* Maximum distance to search for neighboring points in plane fits */
static float sMaxFitDist = 2048.; /* 8 */
/* Maximum number of points in plane fits */
static int sMaxNumFit = 15;      /* 9 */
/* Minimum # of points for fitting parallel planes */
static int sBiplaneMinFit = 5;   /* 10 */
/* Minimum # of points for fitting one plane */
static int sPlaneMinFit = 4;     /* 11 */
/* Maximum % distance of Z value between nearest and other plane for deferring to 2nd
   round: values > 50 disable deferring points */
static float sMaxRound1Dist = 100.; /* 12 */
/* 1 for minimal output, 2 for exhaustive output */
static int sDebugLevel = 0;      /* 13 */

Function for Parsing Lists

int *parselist (const char *line, int *nlist)

Converts a list entry in the string line into a set of integers, returns a pointer to the list of numbers, and returns the number of values in nlist.  An example of a list is 1-5,7,9,11,15-20. Numbers separated by dashes are replaced by all of the numbers in the range.  Numbers need not be in any order, and backward ranges (10-5) are handled.  Any characters besides digits are valid separators.  A / at the beginning of the string will return a NULL and a value of -1 in nlist; memory allocation errors return a NULL and -2 in nlist.  Parsing stops and the list is returned when a anything besides space, tab, comma, dash, or a digit occurs after a space or tab; otherwise other characters (as well as comma or dash right after the last number) make it return NULL and -3 in nlist.  Negative numbers can be entered provided that the minus sign immediately precedes the number.  E.g.: -3 - -1 or -3--1 will give -3,-2,-1; -3, -1,1 or -3,-1,1 will give -3,-1,1.

int parselistfw(const char *line, int *list, int *nlist, int *limlist, int linelen)

Fortran wrapper to parselist, called by the Fortran parselist2 subroutine. The list is returned into array list and limlist is the size of that array, or 0 if unknown.  The return value is 1 for a memory allocation error, 2 for a bad character in the entry, and -1 for the list too big for the array; in the latter case the portion of the list that fits is returned but parselist2 will exit with an error.  If a slash is entered, the input list is returned unchanged.

Functions for Writing Lists

int writeList(int *list, int numList, int lineLen)

Prints a list of comma-separated ranges for the numList values in list, breaking the list into multiple lines of maximum length lineLen if necessary.  Only ranges in increasing order are recognized.  Returns 1 for memory error.

int writelist(int *list, int *numList, int *lineLen)

Fortran wrapper for writeList

void wrlist(int *list, int *numList)

Fortran wrapper for old wrlist subroutine that used a line length of 80

char *listToString(int *list, int numList)

Converts the numList values in list into a string of comma-separated ranges, where only ranges in increasing order are recognized.  The returned string is allocated with malloc() and should be freed with free().  Returns NULL for memory error.

Histogram Functions

void kernelHistogram(float *values, int numVals, float *bins, int numBins, float firstVal, float lastVal, float h, int verbose)

Computes a standard or kernel histogram from the numVals values in the array values.  The histogram is placed in the array bins, and occupies numBins between firstVal and lastVal. The kernel half-width is set by h, where a triweight kernel equal to (1-(x/h)
2)
3 / (0.9143 * h) is added at each point.  Use 0 for a standard binned histogram.  Set verbose to 1 for a list of values, or 2 for a list of bin values.

void kernelhistogram(float *values, int *numVals, float *bins, int *numBins, float *firstVal, float *lastVal, float *h, int *verbose)

Fortran wrapper for kernelHistogram

int scanHistogram(float *bins, int numBins, float firstVal, float lastVal, float scanBot, float scanTop, int findPeaks, float *dip, float *peakBelow, float *peakAbove)

Scans a histogram for peaks and a dip.  The histogram is in numBins elements of bins, extending from firstVal to lastVal.  It will be scanned between values scanBot and scanTop.  If findPeaks is nonzero, it will find the two highest peaks and return their values in peakBelow and peakAbove, then find the dip between them and returns its value in dip; otherwise it just scans the range for the lowest point and returns the value in dip.  The return value is 1 if it fails to find two peaks.

int scanhistogram(float *bins, int *numBins, float *firstVal, float *lastVal, float *scanBot, float *scanTop, int *findPeaks, float *dip, float *peakBelow, float *peakAbove)

Fortran wrapper for scanHistogram

int findHistogramDip(float *values, int numVals, int minGuess, float *bins, int numBins, float firstVal, float lastVal, float *histDip, float *peakBelow, float *peakAbove, int verbose)

Finds a histogram dip by starting with a high smoothing and dropping to a lower one.  
values - Array of values to form histogram from
numVals - Number of values in the array
bins - Array to build histogram in
numBins - Number of bins to divide histogram into
firstVal, lastVal - Starting and ending value for histogram range
minGuess - If non-zero, it specifies an estimate of the minimum number of items above the dip
verbose - Verbose output flag, passed to kernelHistogram
histDip - Returned with the location of the dip
peakBelow, peakAbove - Returned with the peak values below and above the dip
The return value is 1 if a dip cannot be found after 4 trial H values.

int findhistogramdip(float *values, int *numVals, int *minGuess, float *bins, int *numBins, float *firstVal, float *lastVal, float *histDip, float *peakBelow, float *peakAbove, int *verbose)

Fortran wrapper for findHistogramDip

Functions for Analyzing Gold Beads

void makeModelBead(int boxSize, float beadSize, float *array)

Makes a model bead of radius beadSize in array with dimensions boxSize by boxSize.

void makemodelbead(int *boxSize, float *beadSize, float *array)

Fortran wrapper for makeModelbead.

double beadIntegral(float *array, int nxdim, int nx, int ny, float rCenter, float rInner, float rOuter, float xcen, float ycen, float *cenmean, float *annmean, float *temp, float annPct, float *median)

Finds integral above background of a bead located at xcen, ycen in array, an image nx by ny with X dimension nxdim.  rCenter, rInner, and rOuter are radii of the center and the inner and outer radii of the background annulus.  Returns the center and annular means in cenmean and annmean, and if annPct is supplied with a fractional percentile, returns the percentile value in median, using temp as a temporary array.  temp is not used if annPct is 0.  The return value is center minus annular mean.

Functions for Image Statistics by Sampling

int sampleMinMaxMeanSD(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean, float *sd, float *amin, float *amax)

Estimates mean and, optionally, the SD and the minimum and maximum values from a sample of an image. Returns nonzero for errors.
image = array of pointers to each line of data
type = data type, 0 for bytes, 2 for unsigned shorts, 3 for signed shorts, 6 for floats, 7 for 4-byte integers, 8 for RGB triples of bytes or 9 for RGBA bytes; RGB values are weighted with NTSC weighting
nx, ny = X and Y dimensions of image
sample = fraction of pixels to sample
ixStart, iyStart = starting X and Y index to include
nxUse, nyUse = number of pixels in X and Y to include
mean = returned value of mean
sd = returned value of SD; call with NULL to skip the SD computation
amin, amax = returned values of estimate minimum and maximum; call with both NULL to skip the min and max.

int sampleMeanOnly(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean)

Estimates mean only from a sample of an image by calling sampleMinMaxMeanSD. Returns nonzero for errors.

int sampleMeanSD(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean, float *sd)

Estimates mean and SD from a sample of an image by calling sampleMinMaxMeanSD. Returns nonzero for errors.

int sampleMinMaxMean(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float *mean, float *amin, float *amax)

Estimates mean, minimum and maximum from a sample of an image by calling sampleMinMaxMeanSD. Returns nonzero for errors.

int sampleminmaxmeansd(float *image, int *nx, int *ny, float *sample, int *ixStart, int *iyStart, int *nxUse, int *nyUse, int which, float *mean, float *sd, float *dmin, float *dmax)

Fortran wrapper for sampleMinMaxMeanSD with a floating point array in image.  Set which to 1 for mean only, 2 for mean and SD, 3 for mean, min, and max, and 4 for all 4 values.

int samplemeansd(float *image, int *nx, int *ny, float *sample, int *ixStart, int *iyStart, int *nxUse, int *nyUse, float *mean, float *sd, float *dmin, float *dmax)

Fortran wrapper for sampleMeanSD with a floating point array in image

int typeForSampleMean(int mrcMode)

Returns the type needed for calling the sampleMean routines if mrcMode is one of the MRC_MODE_... (or SLICE_MODE_...) values supported by the routines, otherwise returns -1.

int typeforsamplemean(int *mrcMode)

Fortran wrapper for typeForSampleMean

int getSampleOfArray(void *image, int mode, int nx, int ny, float sampleFrac, int ixStart, int iyStart, int nxUse, int nyUse, float fillToExclude, float *samples, int maxSamples, int *numSamples)

Returns a sample of an image into a float array, sampled on a nearly square grid.
image = image array
mode = data type, a SLICE_MODE_ value; BYTE, USHORT, SHORT, or FLOAT are allowed
nx, ny = X and Y dimensions of image
sample = fraction of pixels to sample; can be set to 1 to get up to maxSamples
ixStart, iyStart = starting X and Y coordinates to sample
nxUse, nyUse = extent of image to sample in X and Y
samples = the array to fill with the values
maxSamples = size of samples array
numSamples = number of values returned
Returns 1 for inadequate number of pixels, or 2 for invalid mode.

int percentileStretch(unsigned char **image, int type, int nx, int ny, float sample, int ixStart, int iyStart, int nxUse, int nyUse, float pctLo, float pctHi, float *scaleLo, float *scaleHi)

Estimates percentile limits for contrast strecthing an image by building a histogram of a sample.
image = line pointers to image
mode = data type, a SLICE_MODE_ value; BYTE, USHORT, SHORT, or FLOAT are allowed
nx, ny = X and Y dimensions of image
sample = fraction of pixels to sample
ixStart, iyStart = starting X and Y coordinates to sample
nxUse, nyUse = extent of image to sample in X and Y
pctLo, pctHi = Percentile levels to find on the low and high end of range (1.0 is 1%)
scaleLo, scaleHi = returned values of those percentile levels
Returns 1 for inadequate number of pixels, 2 for invalid mode, or 3 for memory error.

Functions for Measuring Volume Mean/SD at Multiple Binnings

int multiBinSetup(int binning[][3], int boxSize[][3], int boxSpacing[][3], int numScales, int startCoord[3], int endCoord[3], int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds)

Does initial setup for determining the local mean and standard deviation in an array of boxes within an image volume at a series of binnings (scales).  For all of the array variables showing a dimension of 3, the index in the dimension is 0 for the X, 1 for the Y, and 2 for the Z value.  
Inputs:  
binning         - Binning in X, Y, and Z for each scale  
boxSize         - Size of box to analyze in X, Y, and Z for each scale, in binned pixels   
boxSpacing      - Spacing between adjacent boxes in X, Y, and Z for each scale, in binned pixels  
numScales       - Number of binnings to analyze  
startCoord      - Starting unbinned coordinate of volume to analyze in X, Y, and Z  
endCoord        - Ending coordinate of volume to analyze in X, Y, and Z (inclusive)
Outputs:  
boxStart        - Starting coordinate in binned slices of first box in X, Y, and Z for each scale (equals 0 at start of slice, not startCoord)  
numBoxes        - Number of boxes i nX, Y, and Z for each scale  
bufferStartInds - Array to receive starting index of the binned slice for each scale; must be dimensioned to at least numScales + 1.  The size of a floating point array to allocate for the loaded and binned slices is returned in the extra element.  
statStartInds   - Array to receive starting index of the box mean and SD values for each scale; must be dimensioned to at least numScales + 1.  The size of floating point arrays to allocate for the means and SDs is returned in the extra element.  
Returns 1 for inappropriate coordinate limits, 2 for more than the number of scales defined by MAX_MBS_SCALES, 3 for box size bigger than the binned size of the volume at some scale, or 4 for boxSpacing less than 1.

int multibinsetup(int binning[][3], int boxSize[][3], int boxSpacing[][3], int *numScales, int *startCoord, int *endCoord, int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds)

Fortran wrapper for multiBinSetup.  In Fortran, the 2-D arrays would all be dimensioned (3,*), with the X/Y/Z index in the first dimension.

int multiBinStats(int binning[][3], int boxSize[][3], int boxSpacing[][3], int numScales, int startCoord[3], int endCoord[3], int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds, float *buffer, float *means, float *SDs, int *funcData, int (*getSliceFunc)(int *, int *, float *))

Computes the local mean and standard deviation in an array of boxes within an image volume at a series of binnings.  binning, boxSize, boxSpacing, numScales, startCoord, endCoord, boxStart, numBoxes, bufferStartInds, and statStartInds must be the same variables supplied to multiBinSetup.  buffer is an array allocated to the size given by the value after numScales values in bufferStartInds.  Mean and standard deviation values are returned in means and SDs, which must be allocated to the value after numScales values in statStartInds.  The callback function getSliceFunc is called to get the one slice of data within the given coordinate range by getSliceFunc(&iz, funcData, buffer), where iz is the Z coordinate and funcData is filled with whatever the loading function requires (i.e., if it needs the starting and ending X and Y coordinates, they must be passed in funcData).  Returns an error code from getSliceFunc.

int multibinstats(int binning[][3], int boxSize[][3], int boxSpacing[][3], int *numScales, int *startCoord, int *endCoord, int boxStart[][3], int numBoxes[][3], int *bufferStartInds, int *statStartInds, float *buffer, float *means, float *SDs, int *funcData, int (*getSliceFunc)(int *, int *, float *))

Fortran wrapper to multiBinStats

void makeStandardDevMap(float *array, int nxDim, int ixStart, int ixEnd, int iyStart, int iyEnd, int binning, int boxSize, float *sdArr, float *sumArr, float *sqrArr, int *xOffset, int *yOffset)

Makes an image with the local standard deviation at each pixel over a square area given by boxSize.  The input image is in array, with X dimension nxDim, and an image is extracted with binning binning (which can be 1) over the coordinate range given by ixStart, ixEnd, iyStart, iyEnd, inclusive.  The output is contiguously packed into sdArr and will have size (ixEnd + 1 - ixStart) / binning by (iyEnd + 1 - iyStart) / binning.  Two arrays of the same size, sumArr and sqrArr, must be provided.  xOffset and yOffset are returned with offsets to add get from a coordinate in the full input image to coordinate in the SD map:
ixSD = ix / binning + xOffset   and similarly for Y.

Functions for Working with Montage Piece Lists

int checkPieceList(int *pclist, int stride, int npclist, int redfac, int nframe, int *minpiece, int *npieces, int *noverlap)

Examines a list of npclist piece coordinates in pclist for one dimension (x or y) at a spacing of stride between successive values, applies a reduction factor redfac, and given the frame size nframe, it finds the minimum coordinate minpiece, the # of pieces npieces, and the overlap noverlap. It also checks that ALL coordinates on the list are multiples of frame size minus overlap.  Upon failure, it returns the line number at which that  check fails, and also return -1 in npieces.

void checklist(int *pclist, int *npclist, int *redfac, int *nframe, int *minpiece, int *npieces, int *noverlap)

Fortran wrapper for checkPieceList which assumes the stride is 1.  Upon error, it prints a message, and still returns -1 in npieces.

void adjustPieceOverlap(int *pclist, int stride, int npclist, int nframe, int minpiece, int noverlap, int newOverlap)

Adjusts a list of npclist piece coordinates in pclist for one dimension (x or y), at a spacing of stride between successive values, changing the overlap from noverlap to newOverlap, given the frame size nframe and the minimum coordinate minpiece (which is retained).

void adjustpieceoverlap(int *pclist, int *npclist, int *nframe, int *minpiece, int *noverlap, int *newOverlap)

Fortran wrapper for adjustPieceOverlap that assumes a stride of 1.

void fillListOfPieceZ(int *izPcList, int nPcList, int *listZ, int *numListZ)

Examines the list of z values in a piece list (nPcList values in array izPcList) and returns an ordered list of the unique values (numListZ values in array listZ)

int readPieceList(const char *pieceFile, int *ixPcList, int *iyPcList, int *izPcList, int *nPcList, int maxPieces)

Reads a list of piece coordinates from pieceFile into arrays ixPcList, iyPcList, and izPcList, whose size is in maxPiece.  Returns the number of pieces in nPcList.  The return value is 1 for an error opening the file, or one of the negative error codes from readLinesForValues, in which case exitFromValueReadError can be called with the code to exit with an error message.  It simply returns with 0 if pieceFile is NULL or empty.

Functions for Finding Alignments of Montage Pieces

void montXCBasicSizes(int ixy, int nbin, int indentXC, int *nxyPiece, int *nxyOverlap, float aspectMax, float extraWidth, float padFrac, int niceLimit, int *indentUse, int *nxyBox, int *numExtra, int *nxPad, int *nyPad, int *maxLongShift)

Sets up most of the sizes for the overlap zone correlations.  Inputs:  
ixy           - 0 or 2 for X edge, 1 or 3 for Y edge; a value > 1 makes it adjust the box length for the expected shift in that direction.  If you want to supply expected  shifts, you also need to pass an overlap in the edge direction that is adjusted for the nearest integer to a negative expected shift in that direction:
nominalOverlap + max(0, -expectedShift)  
Shifts are the amount that the upper piece has to be shifted to be in alignment with the lower one.  
Inputs:  
nbin          - Binning
indentXC      - Border from edge of image  
nxyPiece      - Size of pieces in X and Y
nxyOverlap    - Nominal overlap between pieces in X and Y for ixy <= 1; for ixy > 1, the overlap in the edge direction should be increased for negative expected shift as indicated above, and the value passed in the long direction should be the nearest integer to the expected shift in that direction
direction
aspectMax     - Maximum aspect ratio to correlate
extraWidth    - Fraction of overlap zone width to add for extra extent
padFrac       - Fraction of box size to pad on each edge
niceLimit     - Largest prime factor for FFT sizes
Outputs:  
indentUse     - Actual border being used
nxyBox        - Binned size  in X and Y of boxes to be extracted from images
numExtra      - Number of extra pixels in X and Y
nxPad         - Size of padded image in X  
nyPad         - Size of padded image in Y  
maxLongShift  - Maximum shift along the long axis of the overlap zone

void montxcbasicsizes(int *ixy, int *nbin, int *indentXC, int *nxyPiece, int *nxyOverlap, float *aspectMax, float *extraWidth, float *padFrac, int *niceLimit, int *indentUse, int *nxyBox, int *numExtra, int *nxPad, int *nyPad, int *maxLongShift)

Fortran wrapper for montXCBasicSizes.  ixy should be 1 or 2.

void montXCIndsAndCTF(int ixy, int *nxyPiece, int *nxyOverlap, int *nxyBox, int nbin, int indentUse, int *numExtra, int nxPad, int nyPad, int numSmooth, float sigma1, float sigma2, float radius1, float radius2, int evalCCC, int *ind0Lower, int *ind1Lower, int *ind0Upper, int *ind1Upper, int *nxSmooth, int *nySmooth, float *ctf, float *delta)

Sets up indices for extracting boxes, and the filter function.  Inputs: ixy           - 0 or 2 for X edge, 1 or 3 for Y edge; a value > 1 makes it adjust the indexes in the long direction to account for an expected shift in nxyOverlap.  If you want to supply expected shifts, you also need to pass an overlap in the edge direction that is increased for negative expected shift in the edge direction, as described for montXCBasicSizes.  Inputs:
nxyPiece      - Size of pieces in X and Y
nxyOverlap    - Nominal overlap between pieces in X and Y for ixy <= 1; for ixy > 1, the overlap in the edge direction should be increased for negative expected shift as indicated above, and the value passed in the long direction should be the nearest integer to the expected shift in that direction
nxyBox        - Binned size in X and Y of boxes to be extracted from images
nbin          - Binning
indentUse     - Border from edge of image  
numExtra      - Number of extra pixels in X and Y
nxPad         - Size of padded image in X  
nyPad         - Size of padded image in Y  
numSmooth     - Number of pixels of smoothing if possible  
sigma1        - Sigma for inverted gaussian at low frequency
sigma2        - Sigma for high frequency filter
radius1       - Radius out to which low frequency filter is 0
radius2       - Radius for high frequency filter
evalCCC       - 1 to evaluate correlation coefficients
Outputs:  
ind0Lower     - Starting index to extract in X and Y for lower piece
ind1Lower     - Ending index to extract in X and Y for lower piece
ind0Upper     - If ixy <= 1, starting index to extract in the ixy dimension for upper piece; otherwise this must be a 2-element array to hold indexes in both dimensions, the index in X then the index in Y
ind1Upper     - Ending index to extract in the ixy dimension (for ixy <= 1) or ending indexes to extract in both dimensions (fox ixy > 1) for upper piece, the index in X then the index in Y
nxSmooth      - Size of edge-smoothed image in X
nySmooth      - Size of edge-smoothed image in Y
ctf           - Array of filter values; must be dimensioned at least 8193
delta         - Change in radius per index in the ctf array

void montxcindsandctf(int *ixy, int *nxyPiece, int *nxyOverlap, int *nxyBox, int *nbin, int *indentUse, int *numExtra, int *nxPad, int *nyPad, int *numSmooth, float *sigma1, float *sigma2, float *radius1, float *radius2, int *evalCCC, int *ind0Lower, int *ind1Lower, int *ind0Upper, int *ind1Upper, int *nxSmooth, int *nySmooth, float *ctf, float *delta)

Fortran wrapper for montXCIndsAndCTF.  ixy should be 1 or 2.

int montXCFindBinning(int maxBin, int targetSize, int indentXC, int *nxyPiece, int *nxyOverlap, float aspectMax, float extraWidth, float padFrac, int niceLimit, int *numPaddedPix, int *numBoxedPix)

Finds binning needed to keep boxed out area smaller than a target size.  Do not use this routine if expected shifts are to be supplied.  Inputs:
maxBin        - Maximum binning to select
targetSize    - Target size to make the number of boxed pixels be less than the square of
indentXC      - Border from edge of image to assume
nxyPiece      - Size of pieces in X and Y
nxyOverlap    - Overlap between pieces in X and Y
aspectMax     - Maximum aspect ratio to correlate
extraWidth    - Fraction of overlap zone width to add for extra extent
padFrac       - Fraction of box size to pad on each edge
niceLimit     - Largest prime factor for FFT sizes
Outputs:  
numPaddedPix  - Total number of pixels for padded images, with extra allowance
numBoxedPix   - Total number of pixels for boxed images, with extra allowance
The return value is the binning.

int montxcfindbinning(int *maxBin, int *targetSize, int *indentXC, int *nxyPiece, int *nxyOverlap, float *aspectMax, float *extraWidth, float *padFrac, int *niceLimit, int *numPaddedPix, int *numBoxedPix)

Fortran wrapper for montXCFindBinning.

int montXCFindBinning2(int maxBin, int targetSize, int indentXC, int ixy, int *nxyPiece, int *nxyOverlap, int *expectedShift, float aspectMax, float extraWidth, float padFrac, int niceLimit, int *numPaddedPix, int *numBoxedPix)

Finds binning needed to keep boxed out area smaller than a target size along one edge, with expected shift at the edge taken into account.  Inputs:
maxBin        - Maximum binning to select
targetSize    - Target size to make the number of boxed pixels be less than the square of
ixy           - 0 for X edge, 1 for Y edge
indentXC      - Border from edge of image to assume
nxyPiece      - Size of pieces in X and Y
nxyOverlap    - Nominal overlap between pieces in X and Y; it will increase the overlap for a negative expected shift in the edge direction
expectedShift - Nearest integers to expected shifts in X and Y needed to align the upper piece to the lower one
aspectMax     - Maximum aspect ratio to correlate
extraWidth    - Fraction of overlap zone width to add for extra extent
padFrac       - Fraction of box size to pad on each edge
niceLimit     - Largest prime factor for FFT sizes
Outputs:  
numPaddedPix  - Total number of pixels for padded images, with extra allowance
numBoxedPix   - Total number of pixels for boxed images, with extra allowance
The return value is the binning.

int montxcfindbinning2(int *maxBin, int *targetSize, int *indentXC, int *ixy, int *nxyPiece, int *nxyOverlap, int *expectedShift, float *aspectMax, float *extraWidth, float *padFrac, int *niceLimit, int *numPaddedPix, int *numBoxedPix)

Fortran wrapper for montXCFindBinning2.

void montXCorrEdge(float *lowerIn, float *upperIn, int *nxyBox, int *nxyPiece, int *nxyOverlap, int nxSmooth, int nySmooth, int nxPad, int nyPad, float *lowerPad, float *upperPad, float *lowerCopy, int numXcorrPeaks, int legacy, float *ctf, float delta, int *inExtra, int nbin, int ixy, int maxLongShift, int weightCCC, float *xDisplace, float *yDisplace, float *CCC, void (*twoDfft)(float *, int *, int *, int *), void (*dumpEdge)(float *, int *, int *, int *, int *, int *), char *debugStr, int debugLen, int debugLevel)

Performs Fourier correlations and evaluation of real-space correlations to find displacement on an edge.  Whether the CCC's are evaluated depends on the value of numXcorrPeaks.  If it is 1, they are not computed, but 16 peaks are found and the first peak is taken that does not exceed the lateral shift in maxLongShift.  If it is greater than 1, at least 16 peaks are still found and checked against maxLongShift, then the CCC is evaluated at the given number of peaks.  This evaluation is done by dividing the overlap for a particular peak position into a set of overlapping subareas of fixed size for different peak positions (typically 6-10 subareas will be done when the displacement is near 0,0).  In each subarea, a search is done from the original peak position to find the highest weighted cross-correlation, where the weighting is by the local standard deviation after binning the correlated images by 2 (in addition to whatever binning is used for the original correlations). Inputs:  
lowerIn       - Boxed, possibly binned image extracted from lower piece
upperIn       - Boxed, possibly binned image extracted from upper piece
nxyBox        - Size of boxed input images in X and Y (binned)
nxyPiece      - Size of full pieces in X and Y (unbinned)
nxyOverlap    - Nominal overlap between pieces in X and Y (unbinned)
nxSmooth      - Size of edge-smoothed image in X
nySmooth      - Size of edge-smoothed image in Y
nxPad         - Size of padded image in X  
nyPad         - Size of padded image in Y  
lowerPad      - Temporary array for lower padded piece
upperPad      - Temporary array for upper padded piece
lowerCopy     - Temporary array for copy of lower padded piece, needed only if evaluating local CCC's at multiple peaks or if the trimmed maximum SD is desired, since it is needed to compute that
numXcorrPeaks - Number of correlation peaks to examine
legacy        - Non-zero to do legacy correlations
ctf           - Array with filter function
delta         - Change in radius per index in the ctf array
inExtra       - Number of extra pixels in X and Y (binned), with Y specified as negative if Y is inverted in the images
nbin          - Binning
ixy           - 0 for X edge, 1 for Y edge
maxLongShift  - Maximum shift along the long axis of the overlap zone
weightCCC     - 1 to weight the CCC by a gaussian value based on the distance from the expected shift.  numXcorrPeaks must be greater than 1 for this weighting to be done   
Outputs, functions, debugging variables:
xDisplace     - Displacement in X: amount to shift upper piece to align to lower. If weightCCC is 2, this is also an input value, with the unbinned expected shift in X, or 0 if there are no expected shifts but there are extra pixels yDisplace     - Displacement in Y, or an input value with expected shift in Y if weightCCC is 2  
CCC           - Value of CCC at the chosen peak, if computed
twoDfft       - 2-D FFT function to receive array, nxPad, nyPad, and 0 for forward or 1 for inverse
dumpEdge      - If non-null, a function for writing images to file.  Its arguments are the image array, X dimension, X size, Y size, ixy + 1,  and 0 for an image or 1 for a correlation  
debugStr      - String to receive debugging text.  To hold all text with full output, it should be numXcorrPeaks + 1 times MONTXC_MAX_DEBUG_LINE
debugLen      - Length of debugLen
debugLevel    - 1 for summary of selected peak and the displacement, 2 for full output about each peak, 3 to include eliminated peaks

void montxcorredge(float *lowerIn, float *upperIn, int *nxyBox, int *nxyPiece, int *nxyOverlap, int *nxSmooth, int *nySmooth, int *nxPad, int *nyPad, float *lowerPad, float *upperPad, float *lowerCopy, int *numXcorrPeaks, int *legacy, float *ctf, float *delta, int *numExtra, int *nbin, int *ixy, int *maxLongShift, int *weightCCC, float *xDisplace, float *yDisplace, float *CCC, void (*twoDfft)(float *, int *, int *, int *), void (*dumpEdge)(float *, int *, int *, int *, int *, int *), int *debugLevel)

Fortran wrapper for montXCorrEdge.  The wrapper will collect and print the debug strings if debugLevel is non-zero.

void montxcorrgetmaxes(int *maxPeak, int *maxLines)

Fortran-callable routine to return maximum number of peaks allowed in maxPeaks and maximum number of debug lines in maxLines.

void montXCSetDistWeightHalfFall(float *inVal)

Sets the distance pixels at which weighting by distance from expected shift falls by half to inVal (callable from Fortran or C)

double montXCGetLastTrimmedMaxSD()

Returns the 95th percentile value of the SD map used for weighted cross-correlation (callable from Fortran or C)

void montXCGetLastRunnersUp(float *disps, int maxPairs)

Returns up to maxPairs X,Y alternative displacements into disps; currently the second and third highest would be returned, or -1.e30, -1.e30 if none was found.

void rowOfThreeCorrs(float *array, float *brray, int nxDim, int ix0, int ix1, int iy0, int iy1, int delX, int delY, float *aWeights, float *bWeights, int nxWgt, int binning, int wgtXoffset, int wgtYoffset, float *corr1, float *corr2, float *corr3, double *sumArr1, double *sumArr2, double *sumArr3)

Computes cross-correlation coefficients at three adjacent shifts in X in subareas of two images.  Arguments are:  
array - image from lower piece
brray - image from upper piece  
nxDim - X dimension  
nx, ny - size of each image
nxTrim, nyTrim - extent of padding on each side in the images; the padded area is excluded from the correlations  
ix0, ix1 - Starting and ending X coordinates in array (inclusive, numbered from 0) to be correlated; coordinates are limited for a particular shift to avoid the padding region  
iy0, iy1 - Starting and ending Y coordinates in array to be correlated
delX, delY - Middle shift between the images (shift of brray relative to array
aWeights, bWeights - weighting factors for pixels in array and brray, respectively; NULL for no weighted correlations  
nxWgt - X dimension of weight arrays  
binning - binning of weight array relative to array and brray  
wgtXoffset, wgtYoffset - offsets to add after dividing by binning to get from index in image array to index in weight array  
corr1, corr2, corr3 - the three CCCs at the three shifts
sumArr1, sumArr2, sumArr3 - Arrays of 6 elements that will receive the weighted sums for three shifts, which can be used to compute the correlation coefficient with weightedCorrFromSums">">weightedCorrFromSums

void columnOfThreeCorrs(float *array, float *brray, int nxDim, int ix0, int ix1, int iy0, int iy1, int delX, int delY, float *aWeights, float *bWeights, int nxWgt, int binning, int wgtXoffset, int wgtYoffset, float *corr1, float *corr2, float *corr3, double *sumArr1, double *sumArr2, double *sumArr3)

Computes cross-correlation coefficients at three adjacent shifts in Y in subareas of two images.  Arguments are the same as for rowOfThreeCorrs

void montXCFindBestCorr(float *array, float *brray, int nxDim, int nx, int ny, int nxTrim, int nyTrim, int ixStart, int ixEnd, int iyStart, int iyEnd, float *delX, float *delY, float *corr, float maxDist, float *aWeights, float *bWeights, int nxWgt, int binning, int wgtXoffset, int wgtYoffset, float threshCCC, double *bestSumArr)

Finds the shift with the best cross-correlation coefficient between overlapping subareas on two images.  Arguments are:  
array - image from lower piece
brray - image from upper piece  
nxDim - X dimension  
nx, ny - size of each image
nxTrim, nyTrim - extent of padding on each side in the images; the padded area is excluded from the correlations  
ixStart, ixEnd - Starting and ending X coordinates in array (inclusive, numbered from 0) to be correlated; coordinates are limited for a particular shift to avoid the padding region  
iyStart, iyEnd - Starting and ending Y coordinates in array to be correlated
delX, delY - Shift of global correlation peak, returned with new shift computed by interpolating among 9 CCCs
corr - best correlation coefficient found  
maxDist - maximum distance to shift from starting value  
aWeights, bWeights - weighting factors for pixels in array and brray, respectively; NULL for no weighted correlations  
nxWgt - X dimension of weight arrays  
binning - binning of weight array relative to array and brray  
wgtXoffset, wgtYoffset - offsets to add after dividing by binning to get from index in image array to index in weight array  
threshCCC - threshold value for aborting search; if the maximum CCC after the first evaluation of 9 points is lower than this, it returns with the current maximum bestArrSum - if non-NULL, an array of 6 elements that will receive the weighted sums that can be used to compute the correlation coefficient with weightedCorrFromSums">">weightedCorrFromSums

void montBigSearch(float *array, float *brray, int nx, int ny, int ixBox0, int iyBox0,int ixBox1, int iyBox1, float *dxMin, float *dyMin, float *sdMin, float *ddenMin, int numIter, int limStep)

Compares images in two arrays array and brray (dimensioned nx, ny, with image dimensions nx by ny), and finds the displacements between the two images with the minimum standard deviation of the pixel-by-pixel difference. ixBox0, iyBox0, ixBox1, and iyBox1 (numbered from 0) define the array index limits of the box to be compared in ARRAY.  dxMin and dyMin, upon entering, should have the starting displacement between the box position in array and the position to be compared in brray.  Initially it will search with a step size of 1, up to a distance of limStep from the initial displacements.  It will do numIter iterations, cutting the step size by a factor of 2 on each iteration.  sxMin and dyMin will be returned with the displacement that has the minimum standard deviation sdMin, and ddenMin is the difference in density at that displacement (B-A).

void montbigsearch(float *array, float *brray, int *nx, int *ny, int *ixBox0, int *iyBox0,int *ixBox1, int *iyBox1, float *dxMin, float *dyMin, float *sdMin, float *ddenMin, int *numIter, int *limStep)

Fortran wrapper to montBigSearch, where the array index limits are numbered from 1.

void montSdCalc(float *array, float *brray, int nx, int ny, int ixBox0, int iyBox0, int ixBox1, int iyBox1, float dx, float dy, float *sd, float *dden)

Compares positions in two image arrays array and brray (each dimensioned to nx, ny, the image dimensions as well), and within a defined box, calculates the standard deviation sd of the pixel-by-pixel difference (B minus A).  ixBox0, iyBox0, ixBox1, and iyBox1 (numbered from 0) define the array index limits of the box in array, and dx and dy define the displacement between that position and the desired position in brray. If dx and dy are integers, the computation is done rapidly between corresponding pixels; otherwise, quadratic interpolation is used to find the pixel value in brray for a given pixel in array.

void montsdcalc(float *array, float *brray, int *nx, int *ny, int *ixBox0, int *iyBox0, int *ixBox1, int *iyBox1, float *dx, float *dy, float *sd, float *dden)

Fortran wrapper to montSdCalc, where the array index limits are numbered from 1.

int findPieceShifts(int *ivarpc, int nvar, int *indvar, int *ixpclist, int *iypclist, float *dxedge, float *dyedge, int idir, int *pieceLower, int *pieceUpper, int *ifskipEdge, int edgeStep, float *dxyvar, int varStep, int *edgeLower, int *edgeUpper, int pcStep, float *work, int fort, int leaveInd, int skipCrit, float robustCrit, float critMaxMove, float critMoveDiff, int maxIter, int numAvgForTest, int intervalForTest, int *numIter, float *wErrMean, float *wErrMax)

Solves for positions of overlapping pieces by adjusting them iteratively to minimize the difference between measured displacement between pairs of pieces and the difference in their positions.
ivarpc: index from included variables (pieces) to overall piece number
nvar: Number of variables
indvar: index from piece number to variable number; must be set to less than the minimum variable number (0 for C, 1 for Fortran) for all pieces potentially connected to the ones included as variables.
ixpclist, iypclist: X and Y piece coordinates.
dxedge, dyedge: the measured difference from the nominal displacement between pieces at an edge
idir: 1 if those values are the amount that the upper piece is displaced from being in register with the lower; -1 if they are the amount that the upper piece needs to be shifted to be in register.
pieceLower, pieceUpper: index of pieces below and above an edge
ifskipEdge: A number indicating whether the edge should be skipped
edgeStep: Stride between X and Y edges at the same edge index in the edge arrays dxedge, dyedge, pieceLower, pieceUpper, ifskipEdge.  If the arrays are accessed in Fortran as array(edge,ixy), then this value is the first dimension of the array.  If they are accessed in C as array[edge][ixy] or array[2*edge+ixy] then the value is 1.
dxyvar: array into which the piece shifts in X and Y are returned for each piece in the variable list
varStep: Stride between X and Y shifts for a given piece in dxyvar; as for edgeStep, this is either 1 or the long dimension of the array.
edgeLower, edgeUpper: edge index of edge below or edge above a given piece in X or Y.
pcStep: Stride between X and Y edges at the same piece in those arrays; again, this is either 1 or the long dimension of the array
work: Array for temporary storage, must be at least 1 plus 20.5 times the number of variables.
fort: A nonzero value indicates that the indexes in ivarpc, indvar, pieceLower, pieceUpper, edgeLower, edgeUpper are numbered from 1 instead 0.
leaveInd: Absolute edge index in edge arrays of edge to leave out
skipCrit: An edge is skipped if ifskipEdge is >= this value
critMaxMove: Terminate if the maximum move of any piece in X or Y is less than this criterion.
robustCrit: Use robust fitting to eliminate or down-weight outlying edge displacements; multiply outlier criterion by given factor.
critMoveDiff: Terminate if the average move changes by less than this amount between samples
maxIter: Maximum number of iterations
numAvgForTest: Number of iterations over which to average the average  
moves in X and Y for the test based on critMoveDiff  
intervalForTest: Number of iterations between such tests  
numIter is returned with the number of iterations.
wErrMean and wErrMax are returned with the mean and maximum of weighted errors.
work is returned with the mean weight for each edge, namely for the upper edge in X then the upper edge in Y for each variable.  
Returns 1 if the strides are not all 1 or all different from 1.
Called from Fortran with identical arguments and name.

int findPieceScalings(int *ivarpc, int nvar, int *indvar, int *ixpclist, int *iypclist, float *ddenEdge, int idir, int *pieceLower, int *pieceUpper, int *ifskipEdge, int edgeStep, float *ddenVar, int *edgeLower, int *edgeUpper, int pcStep, float *work, int fort, int leaveInd, int skipCrit, float critMaxMove, float critMoveDiff, int maxIter, int numAvgForTest, int intervalForTest, int *numIter, float *wErrMean, float *wErrMax)

Solves for differences in relative intensity of overlapping pieces by adjusting them iteratively to minimize the difference between the intensity difference measured in the overlap zones between pairs of pieces and the difference implied by their two scaling factors.  With an idir value of 1, an input relative intensity difference should be the intensity of an upper piece divided by that of a lower piece, with 1 subtracted.  Most arguments are the same as described for findPieceShifts; these are the ones that need a separate description: ddenedge: the measured relative intensity difference between pieces at an edge
ddenvar: array into which the relative intensities are returned for each piece in the variable list.  These are values around 0, and pieces should be scaled by 1. / (1. + ddenvar)
pcStep: Stride between X and Y edges at the same piece in those arrays; again, this is either 1 or the long dimension of the array
critMaxMove: Terminate if the maximum change in relative intensity of any piece is less than this criterion.
critMoveDiff: Terminate if the average change in relative intensity changes by less than this amount between samples
numAvgForTest: Number of iterations over which to average the average  
changes in relative intensity for the test based on critMoveDiff  
wErrMean and wErrMax are returned with the mean and maximum of the fit errors.
Returns 1 if the strides are not all 1 or all different from 1.
Called from Fortran with identical arguments and name.

int pickAlternativeShifts(int *ivarpc, int nvar, int *indvar, float *dxedge, float *dyedge, int *pieceLower, int *pieceUpper, int *ifskipEdge, int edgeStep, int *edgeLower, int *edgeUpper, int pcStep, int fort, float *altDxys, int numAlts, int altIxy, float errThresh, float reduceFac, float newThresh, int *fixedEdges, int *numFixed)

Tests alternative peak positions in all 2x2 sets of pieces with non-skipped edges and replaces a peak position if it gives a big enough reduction in the error implied by the shifts along the 4 edges.
ivarpc: index from included variables (pieces) to overall piece number
nvar: Number of variables
indvar: index from piece number to variable number; must be set to less than the minimum variable number (0 for C, 1 for Fortran) for all pieces potentially connected to the ones included as variables.
dxedge, dyedge: the measured difference from the nominal displacement between pieces at an edge (can be amounts to shift or displacements from alignment)
pieceLower, pieceUpper: index of pieces below and above an edge
ifskipEdge: A number indicating whether the edge should be skipped
edgeStep: Stride between X and Y edges at the same edge index in the edge arrays dxedge, dyedge, pieceLower, pieceUpper, ifskipEdge.  If the arrays are accessed in Fortran as array(edge,ixy), then this value is the first dimension of the array.  If they are accessed in C as array[edge][ixy] or array[2*edge+ixy] then the value is 1.
edgeLower, edgeUpper: edge index of edge below or edge above a given piece in X or Y.
pcStep: Stride between X and Y edges at the same piece in those arrays; again, this is either 1 or the long dimension of the array
fort: A nonzero value indicates that the indexes in ivarpc, indvar, pieceLower, pieceUpper, edgeLower, edgeUpper are numbered from 1 instead 0.
altDxys: Set of alternative differences that can be substituted into dxedge, dyedge.  These must be in a 1-D array with all values for X edges first, followed by all values for Y edges  
numAlts: Number of alternatives per edge; X and Y values of each alternative for an edge must be stored sequentially, at an index numAlts * 2 times the edge index for an X edge, and altIxy + (numAlts * 2 times the edge index) for a Y edge
altIxy: Amount to add to index for Y edges errThresh: minimum error required for the original shifts before anything will be replaced
reduceFac: maximum factor by which the original error must be reduced (a value less than 1)  
newThresh: minimum error required with the new shifts before anything will be replaced fixedEdges: if non-NULL, is returned with a list of the 0-based 1-D edge indexes (as are used to index dxedge and dyedge as 1-D arrays) for edges that have been replaced  
numFixed: Number of replaced edges, if fixedEdges is non-NULL.  This should be zeroed before a first call; this routine can add edges to the list in later calls

Function for Computing a Scaled, Reduced Power Spectrum

int spectrumScaled(void *image, int type, int nx, int ny, void *spectrum, int padSize, int finalSize, int bkgdGray, float truncDiam, int filtType, void (*twoDfft)(float *, int *, int *, int *))

Computes a symmetrical power spectrum of the image in image, with slice type in type and size in nx and ny.  The image will padded to the square size in padSize, which should be a good size for taking a FFT, and tapered down to its mean inside the edges.  If the negative of padSize is passed, there will be no tapering. The FFT will be taken, the logarithm of the magnitudes will be computed and scaled to occupy a range of 0 to 32000, and this spectrum will be mirrored through the origin.  If finalSize is less than padSize, the spectrum will be reduced with antialiased reduction, using the filter type in filtType. If bkgdGray is less than or equal to 0, the result will be placed in spectrum as an array of shorts.  If bkgdGray is greater than 0, the spectrum will be scaled to range from 0 to 255, with the mean near the edges scaled to a value of bkgdGray, and the mean of pixels in a ring with diameter truncDiam as a fraction finalSize scaled to 255.  This result will be returned in spectrum as an array of bytes.  twoDfft must be supplied with the name of a 2-D FFT function with that calling sequence, (todfft if using libifft in IMOD).  
The behavior is quite different if filtType is negative: 1) Reduction, if any, will be done by Fourier cropping with fourierReduceImage; 2) No logarithm is taken and amplitudes are not scaled; 3) spectrum is returned as floats with the X dimension still padded by 2 from the FFTs, and must be allocated accordingly.
Returns -1 or -2 for the negative of an error in calling selectZoomFilter, 1 to 5 for an error in calling zoomWithFilter, -3 for a memory error, or -4 for finalSize greater than padSize, bkgdGray more than 192, truncDiam negative or more than 0.75, or filtType less than 0 and bkgdGray positive.

void makeAmplitudeSpectrum(float *fftArray, float *spectrum, int padSize, int outXdim)

Makes a centered amplitude spectrum from an FFT of a square image in fftArray and puts it in spectrum.  The absolute value of padSize is the real-space size of the image and outXdim is the X dimension for the output array.  Set padSize positive if an FFT is passed in fftArray (with an assumed X dimension of padSize + 2), or negative if fftArray already contains amplitudes (with an assumed X dimension of (padSize + 2) / 2).

Function for fast n*90 rotation/flip operation

int rotateFlipImage(void *array, int mode, int nx, int ny, int operation, int leftHanded, int invertAfter, int invertCon, void *brray, int *nxout, int *nyout, int numThreads)

Performs any combination of rotation and Y flipping for the image in array with the MRC mode given in mode (byte, signed/unsigned short, or float) and the size in nx and ny.  Set operation to 0-3 for counter-clockwise rotation by 90 * operation, plus 4 for flipping around the Y axis before the rotation or 8 for flipping around Y after.  Set leftHanded 0 for right-handed data (IMOD) or 1 for data stored inverted in Y (SerialEM).  Set invertAfter to include a final inversion in Y, thus making left-handed data ready to write with IMOD routines.  For short data only, invertCon can be set non-zero to invert the contrast between the existing minimum and maximum. The number of threads to use is controlled by numThreads; pass 0 to use the default, which is 2 threads for images between 1.5 and 3K in size or for larger images when the operation does not include a rotation, or 3 threads for larger images with a rotation. The output image is returned in brray and its size in nxout, nyout. The function is relatively fast for rotations because it operates on 8 lines of input data at a time.  Returns 1 for an unsupported data mode, 2 for trying to invert contrast with non-short image, or 2 for an operation out of range.

int rotateflipimage(float *array, int *nx, int *ny, int *operation, float *brray, int *nxout, int *nyout, int *numThreads)

Fortran wrapper for rotateFlipImage that assumes array is a floating point, right-handed image.

Function for Reading Lines of Values

int readLinesForValues(FILE *fp, int *numToGetP, int valSize, char *line, int maxLine, int flags, const char *types, ...)

Reads values from one or more lines of the file pointed to by fp and places them repeatedly into the successive variables listed in .... The types of the variables are provided by a corresponding set of letters in types: "i" for int, "f" for float, or "d" for double.  valSize is the size of the value arrays.  A value of numToGetP greater than zero specifies the number of sets of values to get; otherwise the function will try to get all lines in the file.  Pass in 0 to get all lines in the file, with an error return if they do not fit in the supplied arrays; pass in -1 to get all values up to whatever fits in the arrays, without an error.  The actual number of values obtained is returned in numToGetP. Lines are read into line, whose size is specified by maxLine.  If the bit flag RLFV_SEPARATE_LINES is set in flags, it will read one set of data per line, ignoring any entries past that and generating an error if a line has fewer values than the number of arguments.  Returns -1 for an error reading the file, -2 for end of file before the specified numToGetP values are found, -3 for the whole file not fitting in the arrays, -4 for an error parsing the data or a failure to find all values on a line when reading as separate lines, -5 for a value read for an integer argument that is not close enough to an integer, -6 for a memory error, -7 for programming error. When multiple value arguments are passed, it allocates a temporary array big enough to fit all the data before sorting it into the different arrays.

void exitFromValueReadError(int ierr, const char *descrip)

Given an non-zero error code from readLinesForValues in ierr and a description of the file in descrip, calls exitError with an appropriate error message including the descrip after the words "file of".

Functions for Getting Tilt Angles

void getTiltAngles(int *numViews, float *tilt, int limTilt)

Returns tilt angles to a program that accepts four PIP options for tilt angle entry: TiltFile, TiltAngles, FirstTiltAngle, and TiltIncrement.
numViews should be the number of views, if known, or 0 if it not known, in which case the routine will return the number in this variable.  It may not be 0 if FirstTiltAngle/TiltIncrement are entered.
Tilt angles are returned in tilt.
limTilt should contain the dimensions of tilt.
If a TiltFile is entered, or if TiltAngles are entered, they supercede entries of FirstTiltAngle and TiltIncrement.  Call exitError for any error conditions: no option entered, TiltFile and TiltAngles both entered, start and increment entered if numViews is 0, insufficent angles entered or in file, array not big enough, or errors reading a file.

void readTiltFile(int *numViews, char *filename, float *tilt, int limTilt)

Reads tilt angles or other values, one per line, from file filename into the array tilt, whose size is given in limTilt.  numViews should specify the number of values expected if known, or 0 if not known, in which case it will be returned with the number of files.  Calls exitError for any error conditions: error opening the file, insufficent vales in the file, array not big enough, or errors reading the file.

Color Map Functions

int *cmapStandardRamp()

Returns a pointer to the color ramp specification for the standard false color table used in 3dmod.

int *cmapInvertedRamp()

Returns a pointer to a color ramp specification for an false color table inverted from the one used in 3dmod.

int cmapConvertRamp(int *rampData, unsigned char table[3][256])

Converts a color ramp specification in rampData to a full 256-color table in table.  The first value in the rampData array is the number of color specifications; each set of 4 numbers after that is a red, green, and blue value (range 0-255) and a relative position along the color table.

int cmapReadConvert(char *filename, unsigned char table[3][256])

Reads a color map specification from the file specified by filename and converts it to a complete color table in table.  The file starts with the number of lines of color data.  If there are 256 lines they must be red, green, blue triplets (range 0-255); otherwise each line has a red, green, and blue followed by a relative position in the color table. Returns 1 for error opening a file, 2 for errors reading the file, 3 for an invalid number of lines, or 4 for a memory allocation error.

Standard color ramps

The standard color ramp specification used in 3dmod
static int standardRampData[] =
  { 
    14,
    100,   75,  200,  -530,
    60,    96,  255,  -469,
    0,    175,  177,  -400,
    0,    191,  143,  -383,
    0,    207,   78,  -361,
    90,   255,   60,  -305,
    191,  255,    0,  -259,
    239,  255,    0,  -240,
    255,  255,    0,  -229,
    255,  175,    0,  -172,
    255,  105,    0,  -122,
    255,   45,   55,   -60,
    255,    0,   90,   -40,
    255,    0,  192,    10
  };

/* An inverted color ramp specification, used in model view for mesh normals */
static int invertedRampData[] =
  { 
    14,
    255,    0,  192,  -10,
    255,    0,   90,   40,
    255,   45,   55,   60,
    255,  105,    0,  122,
    255,  175,    0,  172,
    255,  255,    0,  229,
    239,  255,    0,  240,
    191,  255,    0,  259,
    90,   255,   60,  305,
    0,    207,   78,  361,
    0,    191,  143,  383,
    0,    175,  177,  400,
    60,    96,  255,  469,
    100,   75,  200,  530
  };