Dear all,
I have set of 10 images (of identical cells) with different emission ranges. For example, image 1 is of 500 nm, image 2 is of 510 nm and so on... [These 10 images are nothing but spectral images covering the entire emission spectra of a fluorophore]. In conventional analysis, we generate something known as a maximum intensity projection - maximum intensity across all the sections for a particular pixel is assigned to a new image (continued for all the pixels). *What I want is rather than the intensity information, I need a image with the information that would reflect from which section the intensity was chosen. This would result in an image with all the maximum wavelength information. * Thank you so much ! Parijat Sarkar Graduate Student CSIR-CCMB India -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Parijat
The macro below works if your stack contains integers. It adds the slice information as fractional part. The first part of the macro creates a demo stack: e.g. the maximum of the top left square is 190 and occurs in slice#9 (1-based) random("seed", 0); newImage("Demo", "8-bit random", 20, 20, 10); run("Scale...", "x=30 y=30 interpolation=None average create process"); //demo image: in top left square, max intensity=190 and occurs in slice#9 (1-based) run("32-bit"); run("Macro...", "code=v+0.01*z stack"); run("Z Project...", "projection=[Max Intensity]"); run("Macro...", "code=[round(v%1 * 100 +1)]");//(1-based) run("Fire"); On 23. Mar 2018, at 8:09, Parijat Sarkar <[hidden email]> wrote: Dear all, I have set of 10 images (of identical cells) with different emission ranges. For example, image 1 is of 500 nm, image 2 is of 510 nm and so on... [These 10 images are nothing but spectral images covering the entire emission spectra of a fluorophore]. In conventional analysis, we generate something known as a maximum intensity projection - maximum intensity across all the sections for a particular pixel is assigned to a new image (continued for all the pixels). *What I want is rather than the intensity information, I need a image with the information that would reflect from which section the intensity was chosen. This would result in an image with all the maximum wavelength information. * Thank you so much ! Parijat Sarkar Graduate Student CSIR-CCMB India -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
On Friday, 23 March 2018 09:26:08 GMT [hidden email] wrote:
> The macro below works if your stack contains integers. > It adds the slice information as fractional part. Wow, Norbert, that is very clever. Can you please explain syntax of the line: run("Macro...", "code=v+0.001*z stack"); I suppose that v is the intensity and z the slice. What is "code", the result? Is this documented anywhere? Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear Gabriel,
does this <https://imagej.nih.gov/ij/macros/examples/MathMacroDemo.txt> help a bit? Best regards Herbie ::::::::::::::::::::::::::::::::::::::::::::: Am 23.03.18 um 16:06 schrieb Gabriel Landini: > On Friday, 23 March 2018 09:26:08 GMT [hidden email] wrote: >> The macro below works if your stack contains integers. >> It adds the slice information as fractional part. > > Wow, Norbert, that is very clever. > Can you please explain syntax of the line: > run("Macro...", "code=v+0.001*z stack"); > > I suppose that v is the intensity and z the slice. What is "code", the result? > Is this documented anywhere? > > Cheers > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
On Friday, 23 March 2018 15:29:42 GMT [hidden email] wrote:
> does this > <https://imagej.nih.gov/ij/macros/examples/MathMacroDemo.txt> > help a bit? Hi Herbie Thanks. it is quite cryptic, I must say... Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Gabriel,
yes, it is quite cryptic and it takes some time to get acquainted... Here is another example code that creates a disc that is flat for a size-fraction of "flat" and has raised cosine slopes for the remainder of the image size: newImage( "wnd", "32-bit black", 256, 256, 1 ); flat = 0.75; run( "Macro...", "code=[wH=w*0.5; rR=round(wH*"+flat+"); if(d<=rR) v=1; if(d>rR && d<0.5*w) v=0.5*(1+cos((d-rR)*PI/(wH-rR)));]" ); Have fun Herbie ::::::::::::::::::::::::::::::::::::::::::::: Am 23.03.18 um 16:39 schrieb Gabriel Landini: > On Friday, 23 March 2018 15:29:42 GMT [hidden email] wrote: >> does this >> <https://imagej.nih.gov/ij/macros/examples/MathMacroDemo.txt> >> help a bit? > > Hi Herbie > Thanks. it is quite cryptic, I must say... > > Cheers > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Parijat Sarkar
As usual, I tend to go for a Java plugin solution. Here's a first cut:
/** * File: Maximum_Wavelength.java * Author: K.R. Sloan * Last Modified: 22 March 2018 * * Desc: An ImageJ plugin that processes an ImageStack and produces an image * where each pixel is an index naming the slice containing the maximum value */ import ij.*; import ij.plugin.filter.PlugInFilter; import ij.process.*; public class Maximum_Wavelength implements PlugInFilter { private ImagePlus imp; @Override public int setup(String arg, ImagePlus imp) { if(arg.equals("about")) {showAbout(); return DONE;} this.imp = imp; return STACK_REQUIRED + NO_CHANGES + NO_UNDO + DOES_ALL; } @Override public void run(ImageProcessor ip) { ImageStack is = this.imp.getImageStack(); int height = is.getHeight(); int width = is.getWidth(); int depth = is.getSize(); ImageProcessor resultIP = new ByteProcessor(width,height); for(int y=0;y<height;y++) { for(int x=0;x<height;x++) { float[] spectrum = getSpectrum(is,x,y); int maxIndex = maxIndex(spectrum); resultIP.putPixel(x,y,maxIndex); } IJ.showProgress((double)y/(double)height); } ImagePlus resultIPL = new ImagePlus("Maximum Wavelength", resultIP); resultIPL.show(); return; } private void showAbout() { IJ.showMessage("About Maximum_Wavelength...", "This plugin filter processes a Stack and produces a new image" + "where each pixel is a slice index indicating the slice" + "containing the maximum value" ); } private float[] getSpectrum(ImageStack is, int x, int y) { int size = is.getSize(); float[] result = new float[size]; for(int j=0;j<size;j++) result[j] = is.getProcessor(j+1).getPixelValue(x,y); return result; } private int maxIndex(float[] v) { float maxV = 0.0f; int maxIndex = -1; for(int i=0;i<v.length;i++) if(v[i]>maxV) { maxV = v[i]; maxIndex = i; } return maxIndex; } } Obligatory question: I tried to use getVoxels - but failed miserably. After a few attempts, I just rolled my own. This is slower than dirt - but I hope it's clear. And, as always - I welcome corrections to my chronic mis-understanding of the API. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. > On 23 Mar 2018, at 02:09 , Parijat Sarkar <[hidden email]> wrote: > > Dear all, > > I have set of 10 images (of identical cells) with different emission ranges. > For example, image 1 is of 500 nm, image 2 is of 510 nm and so on... > > > [These 10 images are nothing but spectral images covering the entire > emission spectra of a fluorophore]. > > > In conventional analysis, we generate something known as a maximum > intensity projection - maximum intensity across all the sections for a > particular pixel is assigned to a new image (continued for all the pixels). > > > > *What I want is rather than the intensity information, I need a image with > the information that would reflect from which section the intensity was > chosen. This would result in an image with all the maximum wavelength > information. * > > > Thank you so much ! > > > Parijat Sarkar > > Graduate Student > > CSIR-CCMB > > India > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Gabriel Landini
Greetings,
Translate to either 'source code' or 'snippet of code'... If you Plugins->Macro->Record, 'code=' precedes what you type in to the code gui field in the parameter parameter to the run method. I assume that if the v=... does not exist in the code the 'v=' is implicitly prepended to the code. Enjoy, Fred On Fri, March 23, 2018 10:06 am, Gabriel Landini wrote: > On Friday, 23 March 2018 09:26:08 GMT [hidden email] wrote: >> The macro below works if your stack contains integers. >> It adds the slice information as fractional part. > > Wow, Norbert, that is very clever. > Can you please explain syntax of the line: > run("Macro...", "code=v+0.001*z stack"); > > I suppose that v is the intensity and z the slice. What is "code", the result? > Is this documented anywhere? > > Cheers > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Kenneth Sloan-2
Greetings,
I would like to second Kenneth's frustration with my version of fetching the requisite values: for(int iz=0; iz<nz; iz++) { IJ.showStatus("NonLinearFit: z="+iz); IJ.showProgress(((float)iz)/nz); for(int ix=0; ix<nx; ix++) for(int iy=0; iy<ny; iy++) { for(int if=0; if<nf; if++) y[if] = ((FloatProcessor)is.getProcessor(imp.getStackIndex(1,iz+1,if+1))).getf(ix,iy); process(x,y); } } Ages ago, I tried using the various getVoxel(s) methods to no avail. If memory serves, they would always return the same value. So once I got the aforementioned code working I just copy and paste every time I need it; which is always. I would assume that this inner loop can be done extremely more efficiently under the hood than through the interface, i.e., repeated calls to is.getProcessor and imp.getStackIndex are not free; notice the need for showStatus and showProgress. Can the getVoxels and setVoxels methods that include the frame dimension be included. Thanks for listening, Fred On Fri, March 23, 2018 11:30 am, Kenneth Sloan wrote: ... > Obligatory question: I tried to use getVoxels - but failed miserably. After a > few attempts, I just > rolled my own. > > This is slower than dirt - but I hope it's clear. > > And, as always - I welcome corrections to my chronic mis-understanding of the > API. > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Fred,
for getting the values along the z direction, e.g. for fitting, you can do the following: int nSlices = stack.getSize(); ImageProcessor[] inIps = new ImageProcessor[nSlices]; for (int i=0; i<nSlices; i++) inIps[i] = stack.getProcessor(i+1); Calibration cal = imp.getCalibration(); double[] zData = new double[nSlices]; for (int i=0; i<nSlices; i++) zData[i] = cal.getZ(i); double[] fitData = new double[nSlices]; for (int y=0; y<height; y++) { IJ.showProgress((double)y/height); for (int x=0; x<width; x++) { double[] params = null; for (int i=0; i<nSlices; i++) fitData[i] = inIps[i].getPixelValue(x, y); // do the fit for fitData over zData } } } Somewhere I have a Stack_Fitter plugin, I'll upload it to http://imagejdocu.tudor.lu Michael ________________________________________________________________ On 23/03/2018 18:32, Fred Damen wrote: > Greetings, > > I would like to second Kenneth's frustration with my version of fetching the > requisite values: > > for(int iz=0; iz<nz; iz++) { > IJ.showStatus("NonLinearFit: z="+iz); > IJ.showProgress(((float)iz)/nz); > > for(int ix=0; ix<nx; ix++) > for(int iy=0; iy<ny; iy++) { > for(int if=0; if<nf; if++) > y[if] = > ((FloatProcessor)is.getProcessor(imp.getStackIndex(1,iz+1,if+1))).getf(ix,iy); > process(x,y); > } > } > > Ages ago, I tried using the various getVoxel(s) methods to no avail. If > memory serves, they would always return the same value. So once I got the > aforementioned code working I just copy and paste every time I need it; which > is always. > > I would assume that this inner loop can be done extremely more efficiently > under the hood than through the interface, i.e., repeated calls to > is.getProcessor and imp.getStackIndex are not free; notice the need for > showStatus and showProgress. Can the getVoxels and setVoxels methods that > include the frame dimension be included. > > Thanks for listening, > > Fred > > > On Fri, March 23, 2018 11:30 am, Kenneth Sloan wrote: > ... >> Obligatory question: I tried to use getVoxels - but failed miserably. After a >> few attempts, I just >> rolled my own. >> >> This is slower than dirt - but I hope it's clear. >> >> And, as always - I welcome corrections to my chronic mis-understanding of the >> API. >> -- >> Kenneth Sloan >> [hidden email] >> Vision is the art of seeing what is invisible to others. > ... > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Thanks for the info, but all of what I do is in the frame direction of a
hyperstack; the z direction is just another one of the indices to a voxel of data. As far as I can tell, for hyperstacks, there is no way around using imp.getStackIndex in the middle of the inner loop. Thanks, Fred On Fri, March 23, 2018 1:22 pm, Michael Schmid wrote: > Hi Fred, > > for getting the values along the z direction, e.g. for fitting, you can > do the following: > > int nSlices = stack.getSize(); > ImageProcessor[] inIps = new ImageProcessor[nSlices]; > for (int i=0; i<nSlices; i++) > inIps[i] = stack.getProcessor(i+1); > Calibration cal = imp.getCalibration(); > double[] zData = new double[nSlices]; > for (int i=0; i<nSlices; i++) > zData[i] = cal.getZ(i); > > double[] fitData = new double[nSlices]; > for (int y=0; y<height; y++) { > IJ.showProgress((double)y/height); > for (int x=0; x<width; x++) { > double[] params = null; > for (int i=0; i<nSlices; i++) > fitData[i] = inIps[i].getPixelValue(x, y); > // do the fit for fitData over zData > } > } > } > > Somewhere I have a Stack_Fitter plugin, I'll upload it to > http://imagejdocu.tudor.lu > > Michael > ________________________________________________________________ > On 23/03/2018 18:32, Fred Damen wrote: >> Greetings, >> >> I would like to second Kenneth's frustration with my version of fetching the >> requisite values: >> >> for(int iz=0; iz<nz; iz++) { >> IJ.showStatus("NonLinearFit: z="+iz); >> IJ.showProgress(((float)iz)/nz); >> >> for(int ix=0; ix<nx; ix++) >> for(int iy=0; iy<ny; iy++) { >> for(int if=0; if<nf; if++) >> y[if] = >> ((FloatProcessor)is.getProcessor(imp.getStackIndex(1,iz+1,if+1))).getf(ix,iy); >> process(x,y); >> } >> } >> >> Ages ago, I tried using the various getVoxel(s) methods to no avail. If >> memory serves, they would always return the same value. So once I got the >> aforementioned code working I just copy and paste every time I need it; >> which >> is always. >> >> I would assume that this inner loop can be done extremely more efficiently >> under the hood than through the interface, i.e., repeated calls to >> is.getProcessor and imp.getStackIndex are not free; notice the need for >> showStatus and showProgress. Can the getVoxels and setVoxels methods that >> include the frame dimension be included. >> >> Thanks for listening, >> >> Fred >> >> >> On Fri, March 23, 2018 11:30 am, Kenneth Sloan wrote: >> ... >>> Obligatory question: I tried to use getVoxels - but failed miserably. >>> After a >>> few attempts, I just >>> rolled my own. >>> >>> This is slower than dirt - but I hope it's clear. >>> >>> And, as always - I welcome corrections to my chronic mis-understanding of >>> the >>> API. >>> -- >>> Kenneth Sloan >>> [hidden email] >>> Vision is the art of seeing what is invisible to others. >> ... >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Fred,
also for a hyperstack, you can have an initial loop to get the stack indices: int nFrames = imp.getNFrames(); ImageProcessor[] inIps = new ImageProcessor[nFrames]; for (int frame = 1; frame <= nFrames; frame++) inIps = stack.getProcessor(getStackIndex(channel, slice, frame)); double[] fitData = new double[nFrames]; Then you can have the loop over y, x as in my previous example, then the inner loop for (int i=0; i<nFrames; i++) fitData[i] = inIps[i].getPixelValue(x, y); The ImageProcessor.getPixelValue function is needed if you have pixel value calibration and/or want to support all types of ImageProcessors, otherwise there are faster calls available. If you want to fit the data, most computing time goes into the fitting, so there is no point in trying to have very fast code here, anyhow. Michael ________________________________________________________________ On 23/03/2018 20:26, Fred Damen wrote: > Thanks for the info, but all of what I do is in the frame direction of a > hyperstack; the z direction is just another one of the indices to a voxel of > data. As far as I can tell, for hyperstacks, there is no way around using > imp.getStackIndex in the middle of the inner loop. > > Thanks, > > Fred > > > On Fri, March 23, 2018 1:22 pm, Michael Schmid wrote: >> Hi Fred, >> >> for getting the values along the z direction, e.g. for fitting, you can >> do the following: >> >> int nSlices = stack.getSize(); >> ImageProcessor[] inIps = new ImageProcessor[nSlices]; >> for (int i=0; i<nSlices; i++) >> inIps[i] = stack.getProcessor(i+1); >> Calibration cal = imp.getCalibration(); >> double[] zData = new double[nSlices]; >> for (int i=0; i<nSlices; i++) >> zData[i] = cal.getZ(i); >> >> double[] fitData = new double[nSlices]; >> for (int y=0; y<height; y++) { >> IJ.showProgress((double)y/height); >> for (int x=0; x<width; x++) { >> double[] params = null; >> for (int i=0; i<nSlices; i++) >> fitData[i] = inIps[i].getPixelValue(x, y); >> // do the fit for fitData over zData >> } >> } >> } >> >> Somewhere I have a Stack_Fitter plugin, I'll upload it to >> http://imagejdocu.tudor.lu >> >> Michael >> ________________________________________________________________ >> On 23/03/2018 18:32, Fred Damen wrote: >>> Greetings, >>> >>> I would like to second Kenneth's frustration with my version of fetching the >>> requisite values: >>> >>> for(int iz=0; iz<nz; iz++) { >>> IJ.showStatus("NonLinearFit: z="+iz); >>> IJ.showProgress(((float)iz)/nz); >>> >>> for(int ix=0; ix<nx; ix++) >>> for(int iy=0; iy<ny; iy++) { >>> for(int if=0; if<nf; if++) >>> y[if] = >>> ((FloatProcessor)is.getProcessor(imp.getStackIndex(1,iz+1,if+1))).getf(ix,iy); >>> process(x,y); >>> } >>> } >>> >>> Ages ago, I tried using the various getVoxel(s) methods to no avail. If >>> memory serves, they would always return the same value. So once I got the >>> aforementioned code working I just copy and paste every time I need it; >>> which >>> is always. >>> >>> I would assume that this inner loop can be done extremely more efficiently >>> under the hood than through the interface, i.e., repeated calls to >>> is.getProcessor and imp.getStackIndex are not free; notice the need for >>> showStatus and showProgress. Can the getVoxels and setVoxels methods that >>> include the frame dimension be included. >>> >>> Thanks for listening, >>> >>> Fred >>> >>> >>> On Fri, March 23, 2018 11:30 am, Kenneth Sloan wrote: >>> ... >>>> Obligatory question: I tried to use getVoxels - but failed miserably. >>>> After a >>>> few attempts, I just >>>> rolled my own. >>>> >>>> This is slower than dirt - but I hope it's clear. >>>> >>>> And, as always - I welcome corrections to my chronic mis-understanding of >>>> the >>>> API. >>>> -- >>>> Kenneth Sloan >>>> [hidden email] >>>> Vision is the art of seeing what is invisible to others. >>> ... >>> >>> -- >>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >>> >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Gabriel Landini
Hi Gabriel,
Herbie already gave a link to the documentation: > <https://imagej.nih.gov/ij/macros/examples/MathMacroDemo.txt> I simply used the macro recorder and chose: Process>Math>Macro... and forgot to explain. My demo version runs quick enough for the example. But a faster version is shown below, where the per-pixel macro code is only used for a single slice (the projection): --- random("seed", 0); newImage("Demo", "8-bit random", 20, 20, 10); run("Scale...", "x=30 y=30 interpolation=None average create process"); //demo image: in top left square, max intensity is 190 and occurs in slice#9 (1-based) //Create a projection of maximum positions run("32-bit"); //stack holding integers, <100 slices for(slc = 1; slc <= nSlices; slc++){ setSlice(slc); run("Add...", "slice value=" + (slc/100) ); } run("Z Project...", "projection=[Max Intensity]"); run("Macro...", "code=[round(v%1 * 100)]"); rename("Max_Positions"); run("Fire"); --- best regards, Norbert > > On 23. Mar 2018, at 16:06, Gabriel Landini <[hidden email]> wrote: > > On Friday, 23 March 2018 09:26:08 GMT [hidden email] wrote: >> The macro below works if your stack contains integers. >> It adds the slice information as fractional part. > > Wow, Norbert, that is very clever. > Can you please explain syntax of the line: > run("Macro...", "code=v+0.001*z stack"); > > I suppose that v is the intensity and z the slice. What is "code", the result? > Is this documented anywhere? > > Cheers > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Thanks Norbert.
Can I add some comments that might be useful for prospective users: the macro detects the "deepest" slice with the highest intensity. I.e. if the same maximum happens in more than one slice the index returned is the highest in the z direction. If one wants the smallest one, I guess that reversing the stack would do it (and convert the result value accordingly). Any reason to restrict it to 100 slices? Maybe do it with 1000 or so, then check nSlices for >999 at the start and warn the user if so. Using the t1-head and the 1000 multiplier it gets the 129 slices labelled correctly, but using 10000 (yes I know...) slices 9 and 10 get labelled both 9. I suppose there is some effect of the representation/rounding of the 32bit value that we need to be aware of. Another idea: maybe it would be useful to use a temp file duplicated from the original, otherwise running it twice on the same image, the macro adds the fractional part to the original again and returns the wrong index in the result (and also avoids having the original converted to 32bit and with a tiny fractional value added). Thanks again for such a nice idea. Best wishes, Gabriel On Friday, 23 March 2018 20:53:17 GMT [hidden email] wrote: > Herbie already gave a link to the documentation: > > <https://imagej.nih.gov/ij/macros/examples/MathMacroDemo.txt> > > I simply used the macro recorder and chose: > Process>Math>Macro... > and forgot to explain. > > > My demo version runs quick enough for the example. But a faster version is > shown below, where the per-pixel macro code is only used for a single slice > (the projection): -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Gabriel,
good idea to duplicate the file, which I have done in the version below. And thanks for pointing out that a maximum can occur several times. I also documented the limitations. These depend on the number of bits needed for the stacks's brightest pixel, as the remainder of the 23 bit mantissa can be used for the z-identifiers. (In the 16-bit T1 sample image you mentioned, the maximum pixel is at ~800, so there is plenty room). The new version (below) automatically subdivides the fractional part (0 to <1) into the needed bins to identify the slices, so I don't need to use a fixed number like "100" in the previous version (but it has become a bit more cryptic). //Part A: Creating a demo stack close("Demo*"); random("seed", 0); newImage("Demo", "8-bit random", 20, 20, 10); run("Scale...", "x=30 y=30 interpolation=None average create process"); //demo image: in top left square, max intensity is 190 and occurs in slice#9 (1-based) //Part B: //From an 8- or 16-bit stack, a map of maximum positions is created //Limit for 8 bit: 32K slices //limit for 16 bit images: 127 slices run("Duplicate...", "title=Demo32 duplicate"); run("32-bit"); //still holding integers maxSlc=nSlices; for(slc = 0; slc < nSlices; slc++){ setSlice(slc + 1); run("Add...", "slice value=" + (slc/maxSlc) );//add fractional slice identifiers } run("Z Project...", "projection=[Max Intensity]"); run("Macro...", "code=round(1+v%1*"+ maxSlc +")"); //isolate and multiply fractional part rename("Demo_Max_Positions"); run("Fire"); close("Demo32"); best regards, Norbert > On 24. Mar 2018, at 12:33, Gabriel Landini <[hidden email]> wrote: > > Thanks Norbert. > Can I add some comments that might be useful for prospective users: the macro > detects the "deepest" slice with the highest intensity. I.e. if the same > maximum happens in more than one slice the index returned is the highest in > the z direction. If one wants the smallest one, I guess that reversing the > stack would do it (and convert the result value accordingly). > > Any reason to restrict it to 100 slices? Maybe do it with 1000 or so, then > check nSlices for >999 at the start and warn the user if so. > Using the t1-head and the 1000 multiplier it gets the 129 slices labelled > correctly, but using 10000 (yes I know...) slices 9 and 10 get labelled both > 9. I suppose there is some effect of the representation/rounding of the 32bit > value that we need to be aware of. > > Another idea: maybe it would be useful to use a temp file duplicated from the > original, otherwise running it twice on the same image, the macro adds the > fractional part to the original again and returns the wrong index in the > result (and also avoids having the original converted to 32bit and with a tiny > fractional value added). > > Thanks again for such a nice idea. > Best wishes, > > Gabriel > > > On Friday, 23 March 2018 20:53:17 GMT [hidden email] wrote: >> Herbie already gave a link to the documentation: >>> <https://imagej.nih.gov/ij/macros/examples/MathMacroDemo.txt> >> >> I simply used the macro recorder and chose: >> Process>Math>Macro... >> and forgot to explain. >> >> >> My demo version runs quick enough for the example. But a faster version is >> shown below, where the per-pixel macro code is only used for a single slice >> (the projection): > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Gabriel Landini
Hello all,
when using: File.copy(path1, path2); the modification date of the the copied file changes to "now". This is not correct and misleading, as the file content was not changed. When going to: https://stackoverflow.com/questions/21215883/preserve-file-creation-time-with-java I find the method: Files.copy(source, target, StandardCopyOption.COPY_ATTRIBUTES); which should be supported from Java 7, However, I did not succeed to get it work My questions: a) wouldn't it make sense that the File.copy method preserves the modification date? b) Is there somewhere a working Java snippet that I can get working? Best, Norbert -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Norbert,
well, I couldn't find a File.copy method in the documentation of Java 7 or Java 8. Do you refer to the ImageJ File.copy macro function? Its code is here: https://github.com/imagej/imagej1/blob/master/ij/macro/Functions.java#lL4204 Already the early Java versions have long File.lastModified() and File.setLastModified(long time) I think you can use these to transfer the modification date (I have not tried). (If this might be useful for others, maybe we could have the file copying function in somewhere in ij.utils or IJ.java, maybe preserving the date?) Michael ________________________________________________________________ On 2018-03-25 17:16, Norbert Vischer wrote: > Hello all, > > when using: > > File.copy(path1, path2); > > the modification date of the the copied file changes to "now". > This is not correct and misleading, as the file content was not > changed. > > When going to: > https://stackoverflow.com/questions/21215883/preserve-file-creation-time-with-java > I find the method: > Files.copy(source, target, StandardCopyOption.COPY_ATTRIBUTES); > which should be supported from Java 7, > However, I did not succeed to get it work > > My questions: > > a) wouldn't it make sense that the File.copy method preserves the > modification date? > b) Is there somewhere a working Java snippet that I can get working? > > Best, Norbert > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by vischer
> On Mar 25, 2018, at 11:16 AM, Norbert Vischer <[hidden email]> wrote:
> > Hello all, > > when using: > > File.copy(path1, path2); > > the modification date of the the copied file changes to "now". > This is not correct and misleading, as the file content was not changed. > > When going to: > https://stackoverflow.com/questions/21215883/preserve-file-creation-time-with-java > I find the method: > Files.copy(source, target, StandardCopyOption.COPY_ATTRIBUTES); > which should be supported from Java 7, > However, I did not succeed to get it work > > My questions: > > a) wouldn't it make sense that the File.copy method preserves the modification date? In the latest daily build (1.52a17), the File.copy() macro function preserves the modification date. > b) Is there somewhere a working Java snippet that I can get working? File.copy() uses the Tools.copyFile() method, reproduced below. -wayne /** Copies the contents of the file at 'path1' to 'path2', returning an error message (as a non-empty string) if there is an error. Based on the method with the same name in Tobias Pietzsch's TifBenchmark class. */ public static String copyFile(String path1, String path2) { File f1 = new File(path1); File f2 = new File(path2); try { if (!f1.exists() ) return "Source file does not exist"; if (!f2.exists() ) f2.createNewFile(); long time = f1.lastModified(); FileInputStream stream1 = new FileInputStream(f1); FileChannel channel1 = stream1.getChannel(); FileOutputStream stream2 = new FileOutputStream(f2); final FileChannel channel2 = stream2.getChannel(); if (channel2!=null && channel1!=null ) channel2.transferFrom(channel1, 0, channel1.size()); channel1.close(); stream1.close(); channel2.close(); stream2.close(); f2.setLastModified(time); } catch(Exception e) { return e.getMessage(); } return ""; } -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Thanks Wayne and Michael,
the macro command in the new daily build is all what I wanted. Best regards, Norbert -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |