Remove those entries that have an error of “Permission Denied” :
find /opt -name dcm 2>/dev/null
Filter the output of a program and redirect the filtered result into a file:
./bin/programA -i ... -o ... 2>&1 | grep "keywords" > a.txt
A blog about coding
Remove those entries that have an error of “Permission Denied” :
find /opt -name dcm 2>/dev/null
Filter the output of a program and redirect the filtered result into a file:
./bin/programA -i ... -o ... 2>&1 | grep "keywords" > a.txt
Create a virtual environment:
$ python3 -m venv myenv
Activate it:
$ source myenv/bin/activate
[myenv] $
Leave/Deactivate it:
[myenv] $ deactivate
$
A simplest way to build ImageJ is using Apache Ant.
For example,
./apache-ant/bin/ant -buildfile build.xml
But before that, JAVA_HOME should be set first.
export JAVA_HOME=/usr/java/jdk-12.0.1/
export PATH=$JAVA_HOME:$PATH
If not sure where the jdk is, use the following command to find it:
readlink -f $(which java)
When use jdk-12 to build the latest ImageJA (ImageJA is the old ImageJ, the new ImageJ is different with ImageJA), there will be some issues.
[javac] warning: [options] bootstrap class path not set in conjunction with -source 6
[javac] error: Source option 6 is no longer supported. Use 7 or later.
[javac] error: Target option 6 is no longer supported. Use 7 or later.
SOLUTION: Change ‘source’ and ‘target’ in build.xml from 1.6 to 1.7
source="1.7" target="1.7"
Sure, another alternative is to use the lower version jdk, and it does work in my another machine which installs jdk8 (1.8). Here is the java version history.
Actually, not only this file cannot be found, but there are more files that cannot be found. ImageJA’s code has already been restructured, but not sure why build.xml has not been updated.
SOLUTION: Update those files’ path.
<target name="build" depends="compile" description="Build ij.jar.">
<!-- Copy needed files into the build directory. -->
<copy file="src/main/resources/IJ_Props.txt" todir="build" />
<copy file="src/main/resources/microscope.gif" tofile="build/microscope.gif" />
<copy file="src/main/resources/about.jpg" tofile="build/about.jpg" />
<!--<copy file="plugins/MacAdapter.class" tofile="build/MacAdapter.class" /> -->
<copy todir="build/macros"><fileset dir="src/main/resources/macros"/></copy>
<!-- Build ij.jar. -->
<jar jarfile="ij.jar" basedir="build"
manifest="src/main/resources/META-INF/MANIFEST.MF" />
</target>
After fixing these two issues, the code should be able to be built.
ant -buildfile build.xml
...
BUILD SUCCESSFUL
Then run the built result ij.jar:
java -jar ij.jar
boost::combine() packs a group of variables.
#include <vector>
#include <boost/range/combine.hpp>
int main(int argc, char** argv)
{
// The ranges mush have the same size
std::vector<int> ids = {1, 2, 3, 4};
std::vector<std::string> names = { "A", "B", "C", "D" };
std::vector<float> heights = { 1.71, 1.65, 1.80, 1.75 };
for( const auto &zipped : boost::combine(ids, names, heights) ) {
{
// tie()
int id;
std::string name;
float height;
boost::tie(id, name, height) = zipped;
std::cout << id << "," << name << "," << height << std::endl;
}
{
// get<>()
int id = boost::get<0>( zipped );
std::string name = boost::get<1>( zipped );
float height = boost::get<2>( zipped );
std::cout << id << "," << name << "," << height << std::endl;
}
}
}
Output:
1,A,1.71
1,A,1.71
2,B,1.65
2,B,1.65
3,C,1.8
3,C,1.8
4,D,1.75
4,D,1.75
Note, the boost version used in this example is 1.71.
vivid: a simple-to-use C++ color library
glm: a C++ mathematics library for graphics software based on the OpenGL Shading Language (GLSL) specifications.
Boost::filesystem provides two methods to check if directories exist and create directories if not.
#include <boost/filesystem.hpp>
boost::filesystem::path filePath( "/a/b/c" );
if( !boost::filesystem::exists( filePath ) &&
!boost::filesystem::create_directories( filePath ) ) {
...
}
C++ standard didn’t provide them until C++17.
Boost introduced a new library endian in version 1.58: Types and conversion functions for correct byte ordering and more regardless of processor endianness.
#include <boost/endian/conversion.hpp>
int32_t x;
... read into x from a file ...
boost::endian::big_to_native_inplace(x);
for (int32_t i = 0; i < 1000000; ++i)
x += i;
boost::endian::native_to_big_inplace(x);
... write x to a file ...
As for libpng, here is an example about how to use it to read and write a png. But actually the read() method can be simplified as below.
...
png_read_png( png, info, PNG_TRANSFORM_IDENTITY, NULL );
png_bytepp row_pointers = png_get_rows( png, info );
auto width = png_get_image_width( png, info );
auto height = png_get_image_height( png, info );
...
Note, png_read_png() must be called first before calling png_get_rows(), otherwise the return pointer row_pointers would be invalid. Its manual says:
After you have called png_read_png(), you can retrieve the image data with row_pointers = png_get_rows(png_ptr, info_ptr);
There are two ways of writing XML from a string.
Take the xml data from [2] as an exmaple.
xmlData = """<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>"""
from xml.etree import ElementTree as ET
root = ET.XML(xmlData)
with open('a.xml', 'w') as f:
f.write(ET.tostring(root).decode())
Read the xml file:
tree = ET.parse('a.xml')
rootNode = tree.getroot()
for child in rootNode:
print(child.tag, child.attrib)
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
root = ET.fromstring(xmlData)
Read the root directly:
for child in root:
print(child.tag, child.attrib)
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
[2] https://docs.python.org/2/library/xml.etree.elementtree.html
Some essential definitions:
typedef char Element;
struct Node
{
Node( Element inputData ) : data( inputData ) {
cout << "Construct " << data << endl;
}
~Node() {
cout << "Destruct " << data << endl;
if( lchild != NULL ) {
delete lchild;
lchild = NULL;
}
if( rchild != NULL ) {
delete rchild;
rchild = NULL;
}
}
Element data;
Node *lchild;
Node *rchild;
};
typedef Node* Tree;
// BFS
void breadthFirstSearch(Tree root)
{
queue<Node *> nodeQueue;
nodeQueue.push (root);
Node *node;
while (!nodeQueue.empty()) {
node = nodeQueue.front();
nodeQueue.pop ();
cout << node->data;
if (node->lchild) {
nodeQueue.push(node->lchild);
}
if (node->rchild) {
nodeQueue.push(node->rchild);
}
}
}
// DFS (iterative)
void depthFirstSearch(Tree root)
{
stack<Node *> nodeStack;
nodeStack.push (root);
Node *node;
while (!nodeStack.empty ()) {
node = nodeStack.top();
nodeStack.pop ();
cout << node->data;
if (node->rchild) {
nodeStack.push(node->rchild);
}
if (node->lchild) {
nodeStack.push(node->lchild);
}
}
}
// DFS (recursive)
void depthFirstSearchRecursive(Tree root)
{
if (root) {
cout << root->data;
if (root->lchild) {
depthFirstSearchRecursive(root->lchild);
}
if (root->rchild) {
depthFirstSearchRecursive(root->rchild);
}
}
}
Define a class TreeBuilder to build a tree and destroy it.
class TreeBuilder
{
public:
TreeBuilder( Element data[] ) : index_( 0 ) {
constructTree( root_, data );
}
~TreeBuilder() {
destructTree( root_ );
}
Tree tree() const { return root_ ;}
private:
void constructTree(Tree &root, Element data[])
{
Element e = data[index_++];
if (e == '#') {
root = NULL;
}
else {
root = new Node (e);
constructTree(root->lchild, data);
constructTree(root->rchild, data);
}
}
void destructTree(Tree root) {
if( root != NULL ) {
delete root;
root = NULL;
}
}
private:
int index_;
Tree root_;
};
Test BFS and DFS.
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
...
int main(int argc, char** argv)
{
Element data[15] = { 'A', 'B', 'D', '#', '#', 'E', '#', '#', 'C', 'F','#', '#', 'G', '#', '#' };
TreeBuilder builder( data );
auto tree = builder.tree();
cout << endl;
cout << "BFS result:";
breadthFirstSearch(tree);
cout << endl;
cout << "DFS (iterative) result:";
depthFirstSearch(tree);
cout << endl;
cout << "DFS (recursive) result:";
depthFirstSearchRecursive(tree);
cout << endl;
return 0;
}
Build and run it.
g++ main.cpp --std=c++14
./a.out
Construct A
Construct B
Construct D
Construct E
Construct C
Construct F
Construct G
BFS result:ABCDEFG
DFS (iterative) result:ABDECFG
DFS (recursive) result:ABDECFG
Destruct A
Destruct B
Destruct D
Destruct E
Destruct C
Destruct F
Destruct G
Use valgrind to check if there is any memory leak.
valgrind --leak-check=yes ./a.out
...
==30852== HEAP SUMMARY:
==30852== in use at exit: 0 bytes in 0 blocks
==30852== total heap usage: 12 allocs, 12 frees, 74,024 bytes allocated
==30852==
==30852== All heap blocks were freed -- no leaks are possible
==30852==
==30852== For counts of detected and suppressed errors, rerun with: -v
==30852== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)