text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>PolarScanMatching(PSM): polar_matching/polar_match.h File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css">
<link href="doxygen.css" rel="stylesheet" type="text/css">

Main Page

Classes

Files

File List

File Members

polar_matching/polar_match.h File Reference
#include <stdio.h>

Go to the source code of this file.

Classes

struct  	PMScan

 	Structure describing a laser scan.  More...

Defines

#define 	PM_PSD_SCANNER   0

#define 	PM_HOKUYO_URG_04LX   1

#define 	PM_SICK_LMS200   2

#define 	PM_HOKUYO_UTM_30LX   3

#define 	PM_LASER   PM_HOKUYO_UTM_30LX

#define 	PM_LASER_NAME   "HOKUYO UTM-30LX"

 	The name of the laser range finder.

#define 	PM_L_POINTS   1081

 	Maximum number of points in a scan.

#define 	PM_FOV   270

 	Field of view of the laser range finder in degrees.

#define 	PM_MAX_RANGE   700

 	[cm] Maximum valid laser range. (3000 for this sensor.)

#define 	PM_MIN_VALID_POINTS   300

 	Minimum number of valid points for scan matching.

#define 	PM_SEARCH_WINDOW   200

 	Half window size which is searched for correct orientation.

#define 	PM_CORRIDOR_THRESHOLD   25.0

 	Threshold for angle variation between points to determine if scan was taken of a corridor.

#define 	PM_TIME_DELAY   0

 	[s] Time delay (time registration error) in the laser measurements. Use 0.02 for SLAMbot.

#define 	PM_LASER_Y   0

 	[cm] Y coordinate of the laser on the robot.

#define 	PM_MIN_RANGE   10.0f

 	[cm] Minimum valid laser range for the reprojected current scan.

#define 	PM_SEG_MAX_DIST   20.0

 	The distance between points to break a segment.

#define 	PM_WEIGHTING_FACTOR   70*70

 	Parameter used for weighting associated points in the position calculation of PSM. Try setting it to 30*30 for laser odometry.

#define 	PM_CHANGE_WEIGHT_ITER   10

 	The number of iterations after which the weighting factor is reduced to weight down outliers.

#define 	PM_TYPE   float

 	The variable type used in calculations. Change it to double for higher accuracy and lower speed.

#define 	PM_MAX_ERROR   100

 	[cm] Maximum distance between associated points used in pose estimation. Try setting it to 30 for laser odometry.

#define 	PM_STOP_COND   0.4

 	If the pose change (|dx|+|dy|+|dth|) is smaller than this PSM scan matching stops.

#define 	PM_MAX_ITER   30

 	Maximum number of iterations for PSM.

#define 	PM_MAX_ITER_ICP   60

 	Maximum number of iterations for ICP.

#define 	PM_STOP_COND_ICP   0.1

 	Stopping condition for ICP. The pose change has to be smaller than this.

#define 	PM_MIN_STD_XY   20.0

 	[cm] The minimum match result standard deviation in X or Y direction. Used in covariance estimation.

#define 	PM_MIN_STD_ORIENTATION   4.0

 	[degrees] The minimum standard deviation of the orientation match. Used in covariance estimation.

#define 	PM_MATCH_ERROR_OFFSET   5.0

 	[cm] Offset subtracted from average range residual when scaling the covariance matrix.

#define 	PM_ODO   -1

 	Show results with odometry only in mapping_with_matching().

#define 	PM_PSM   1

 	Polar scan matching - matching bearing association rule.

#define 	PM_ICP   3

 	Scan matching with iterative closest point association rule.

#define 	PM_TIME_FILE   "results/iterations.txt"

 	When generating results, timing is data is saved into this file from the matching algorithms. i|time|ax|ay|ath[deg] is saved. Does not work in the moment.

#define 	PM_RANGE   1

 	Measurement tag: range reading is longer than PM_MAX_RANGE.

#define 	PM_MOVING   2

 	Measurement tag: range reading corresponds to a moving point. Not implemented yet.

#define 	PM_MIXED   4

 	Measurement tag: range reading is a mixed pixel.

#define 	PM_OCCLUDED   8

 	Measurement tag: range reading is occluded.

#define 	PM_EMPTY   16

 	Measurement tag: no measurment (between 2 segments there is no interpolation!).

Functions

void 	pm_init (const char *filename=NULL, FILE **fin=NULL)

 	Initialises internal variables and opens a log file.

int 	pm_readScan (FILE *fin, PMScan *ls)

 	Reads one scan from file fin and stores it in ls.

void 	pm_save_scan (PMScan *act, const char *filename)

 	Saves scan in a text file.

void 	pm_preprocessScan (PMScan *ls)

 	Prepares a scan for scan matching.

PM_TYPE 	pm_psm (const PMScan *lsr, PMScan *lsa)

 	Match two laser scans using polar scan matching.

PM_TYPE 	pm_icp (const PMScan *lsr, PMScan *lsa)

 	Matches two laser scans using the iterative closest point method.

void 	pm_plotScanAt (const PMScan *ls, PM_TYPE x, PM_TYPE y, PM_TYPE th, const char *col, double diameter=2.0, bool connect_lines=false)

 	Plots scan ls at robot/laser pose x, y, th.

void 	pm_plotScan (PMScan *ls, const char *col, double diameter=2.0, bool connect_lines=false)

 	Plots scan ls.

void 	pm_show_segmentation (const PMScan *ls)

 	Shows segmentation results by plotting segments with different colours.

void 	pm_plotScan4Thesis (PMScan *lsr, PMScan *lsa)

 	Plots current and reference scan in the way scans appeared in my thesis.

void 	pm_plotTime4Thesis (PM_TYPE xt, PM_TYPE yt, PM_TYPE tht, int *iter=NULL, double *time=NULL)

 	Generates a convergence speed plot from previously saved result.

bool 	pm_is_corridor (PMScan *act)

 	Guesses if a scan was taken on a corridor.

PM_TYPE 	pm_error_index (PMScan *lsr, PMScan *lsa)

 	Calculates an error index expressing the quality of a match.

PM_TYPE 	pm_error_index2 (PMScan *ref, PMScan *cur, int *associatedPoints=NULL)

 	More quickly calculates an error index expressing the quality of a match.

PM_TYPE 	pm_corridor_angle (PMScan *act)

 	Determines the orientation of a corridor.

void 	pm_cov_est (PM_TYPE err, double *c11, double *c12, double *c22, double *c33, bool corridor=false, PM_TYPE corr_angle=0)

 	Estimates the covariance matrix of a match.

void 	pm_unit_test (int matching_alg=PM_PSM, bool interactive=true)

 	Performs unit tests on scan matching.

Variables

PM_TYPE 	pm_fi [PM_L_POINTS]

 	Contains precomputed range bearings.

PM_TYPE 	pm_si [PM_L_POINTS]

 	Contains the sinus of each bearing.

PM_TYPE 	pm_co [PM_L_POINTS]

 	Contains the cosinus of each bearing.

const PM_TYPE 	PM_D2R

 	Conversion factor for converting degrees to radians.

const PM_TYPE 	PM_R2D

 	Conversion factor for converting radians to degrees.

Define Documentation

          #define PM_CHANGE_WEIGHT_ITER   10

The number of iterations after which the weighting factor is reduced to weight down outliers.

          #define PM_CORRIDOR_THRESHOLD   25.0

Threshold for angle variation between points to determine if scan was taken of a corridor.

          #define PM_EMPTY   16

Measurement tag: no measurment (between 2 segments there is no interpolation!).

          #define PM_FOV   270

Field of view of the laser range finder in degrees.

          #define PM_HOKUYO_URG_04LX   1

          #define PM_HOKUYO_UTM_30LX   3

          #define PM_ICP   3

Scan matching with iterative closest point association rule.

          #define PM_L_POINTS   1081

Maximum number of points in a scan.

          #define PM_LASER   PM_HOKUYO_UTM_30LX

          #define PM_LASER_NAME   "HOKUYO UTM-30LX"

The name of the laser range finder.

          #define PM_LASER_Y   0

[cm] Y coordinate of the laser on the robot.

Set to 0 for ground thruth, simulation, mapping_with_matching. Set to 0 when in doubt and handle the coordinate transforms yourself. Set it to 31.3 for Slambot. The Y axis points in the forward motion direction of a differential drive robot.

          #define PM_MATCH_ERROR_OFFSET   5.0

[cm] Offset subtracted from average range residual when scaling the covariance matrix.

          #define PM_MAX_ERROR   100

[cm] Maximum distance between associated points used in pose estimation. Try setting it to 30 for laser odometry.

          #define PM_MAX_ITER   30

Maximum number of iterations for PSM.

          #define PM_MAX_ITER_ICP   60

Maximum number of iterations for ICP.

          #define PM_MAX_RANGE   700

[cm] Maximum valid laser range. (3000 for this sensor.)

          #define PM_MIN_RANGE   10.0f

[cm] Minimum valid laser range for the reprojected current scan.

          #define PM_MIN_STD_ORIENTATION   4.0

[degrees] The minimum standard deviation of the orientation match. Used in covariance estimation.

          #define PM_MIN_STD_XY   20.0

[cm] The minimum match result standard deviation in X or Y direction. Used in covariance estimation.

          #define PM_MIN_VALID_POINTS   300

Minimum number of valid points for scan matching.

          #define PM_MIXED   4

Measurement tag: range reading is a mixed pixel.

          #define PM_MOVING   2

Measurement tag: range reading corresponds to a moving point. Not implemented yet.

          #define PM_OCCLUDED   8

Measurement tag: range reading is occluded.

          #define PM_ODO   -1

Show results with odometry only in mapping_with_matching().

          #define PM_PSD_SCANNER   0

          #define PM_PSM   1

Polar scan matching - matching bearing association rule.

          #define PM_RANGE   1

Measurement tag: range reading is longer than PM_MAX_RANGE.

          #define PM_SEARCH_WINDOW   200

Half window size which is searched for correct orientation.

          #define PM_SEG_MAX_DIST   20.0

The distance between points to break a segment.

          #define PM_SICK_LMS200   2

          #define PM_STOP_COND   0.4

If the pose change (|dx|+|dy|+|dth|) is smaller than this PSM scan matching stops.

          #define PM_STOP_COND_ICP   0.1

Stopping condition for ICP. The pose change has to be smaller than this.

          #define PM_TIME_DELAY   0

[s] Time delay (time registration error) in the laser measurements. Use 0.02 for SLAMbot.

          #define PM_TIME_FILE   "results/iterations.txt"

When generating results, timing is data is saved into this file from the matching algorithms. i|time|ax|ay|ath[deg] is saved. Does not work in the moment.

          #define PM_TYPE   float

The variable type used in calculations. Change it to double for higher accuracy and lower speed.

          #define PM_WEIGHTING_FACTOR   70*70

Parameter used for weighting associated points in the position calculation of PSM. Try setting it to 30*30 for laser odometry.

Function Documentation

          PM_TYPE pm_corridor_angle
          (
          PMScan *
           act
           )

Determines the orientation of a corridor.

TODO: NEEDS A REWRITE - TOO MESSY.

Assuming the scan was taken of a corridor, determines the orientation of the corridor by finding the maximum in a 180 degree wide angle histogram. The input into the histogram are angles of lines created by connecting neighbouring points.

Normally, this function is used on the reference scan and not the current scan.

Parameters:

	act 	The scan of which oriention is to be determined.

Returns:

The orientation of the corridor.

          void pm_cov_est
          (
          PM_TYPE
           err,

          double *
           c11,

          double *
           c12,

          double *
           c22,

          double *
           c33,

          bool
           corridor,

          PM_TYPE
           corr_angle

          )

Estimates the covariance matrix of a match.

Estimates elements (c11,c12,c22,c33) of a match result covariance matrix of the following structure:

 [c11 c12 0.0]

 [c12 c22 0.0]

 [0.0 0.0 c33]

This function scales a base covariance matrix by an error index:

 C = C0(PM_MIN_STD_XY, PM_MIN_STD_ORIENTATION) * (err - PM_MATCH_ERROR_OFFSET).

 For corridors it scales and rotates a covariance matrix stretched in the direction of the corridor:

 C = Rot(C0, corr_angle) * (err - PM_MATCH_ERROR_OFFSET).

 If (err - PM_MATCH_ERROR_OFFSET) < 1 then C = C0.

Parameters:

	err 	The error index of the match.

	c11,c12,c22,c33 	The estimated covariance matrix elements.

	corridor 	If true, a special estimate with large along-corridor-error is used.

	corr_angle 	The orientation of the corridor. Call pm_corridor_angle on the refernce scan to get this value.

          PM_TYPE pm_error_index
          (
          PMScan *
           lsr,

          PMScan *
           lsa

          )

Calculates an error index expressing the quality of a match.

This function assesses how well is the current scan aligned with the reference scan. This function has to be called after a scan has been matched. The current scan's pose has to be expressed in the reference scan's coordinate system.

The current scan is compared to the reference scan and vice versa, then the maximum is taken. The comparisson is performed by calculating the average closest point distance. Far away points are ignored in the process. The number of non-far away points have to be larger than a threshold.

This function is computationally very expensive and takes a conservative guess on the match quality.

TODO: Improve the accuracy of the estimate. Speed it up. Perhaps should use the error output from scan matching instead. A proper test is necessary.

Parameters:

	lsr 	The reference scan.

	lra 	The current scan.

Returns:

The average minimum Euclidean distance.

          PM_TYPE pm_error_index2
          (
          PMScan *
           ref,

          PMScan *
           cur,

          int *
           associatedPoints

          )

More quickly calculates an error index expressing the quality of a match.

This function assesses how well is the current scan aligned with the reference scan. This function has to be called after a scan has been matched. The current scan's pose has to be expressed in the reference scan's coordinate system.

The current scan is compared to the reference scan by projecting the current scan where the reference scan was taken and calculating the average range residuals.

Parameters:

	lsr 	The reference scan.

	lra 	The current scan.

Returns:

The average minimum Euclidean distance.

          PM_TYPE pm_icp
          (
          const PMScan *
           lsr,

          PMScan *
           lsa

          )

Matches two laser scans using the iterative closest point method.

Minimizes least square error of points through changing lsa->rx, lsa->ry, lsa->th by using ICP. It interpolates associated points. Only the best 80% of points are used in the pose calculation. Scan projection is done at each iteration.

For maintanence reasons changed scan projection to that of psm.

          void pm_init
          (
          const char *
           filename,

          FILE **
           fin

          )

Initialises internal variables and opens a log file.

If filename is present, then it opens the scanfile and reads out the first line. The file pointer is then set to the corresponding file. Before performing any scan matching call this fuction once to initialize important global variables.

Upon failure an exception is thrown.

Parameters:

	filename 	The name of the optional logfile to be used.

	fin 	The optional opened file pointer is returned here.

          bool pm_is_corridor
          (
          PMScan *
           act
           )

Guesses if a scan was taken on a corridor.

Scan matching results on corridors are often inaccurate in the along-corridor direction. By detecting scans with a corridor-like appearance one can tailor a covariance matrix to incorporate the along-corridor uncertainty of the scan matching result.

Calculates the variance of angles between neighbouring Cartesian points as the "corridorness" criterion. On corridoors, the majority of vectors connecting neighbouring points are aligned along one line. Thus corridors generate a sharp peak in an angle histogram.

To solve the problem caused at the 180-0 degree transition point the calculations are repeated after a 30 degree shift. This is a hack which can be fixed easily.

The scan is assumed be pre-processed (segmentation and median filtering).

An exeption is thrown if there is less than 1 valid point.

TODO: Remove the double calculation of the variance.

Parameters:

	act 	The scan which is examined for being corridor-like.

Returns:

True if act seems to be taken of a corridor.

          void pm_plotScan
          (
          PMScan *
           ls,

          const char *
           col,

          double
           diameter,

          bool
           connect_lines

          )

Plots scan ls.

The scan is shifted by PM_LASER_Y.

Parameters:

	ls 	The laser scan to be plotted at the scan's pose.

	col 	The colour of the scan as "red", "green"... See dr_COLORS for more.

	diameter 	[cm] The drawn diameter of the measured points.

	connect_lines 	If true, measured points are connected with lines.

          void pm_plotScan4Thesis
          (
          PMScan *
           lsr,

          PMScan *
           lsa

          )

Plots current and reference scan in the way scans appeared in my thesis.

Parameters:

	lsr 	Reference scan.

	lsa 	Current scan.

          void pm_plotScanAt
          (
          const PMScan *
           ls,

          PM_TYPE
           x,

          PM_TYPE
           y,

          PM_TYPE
           th,

          const char *
           col,

          double
           diameter,

          bool
           connect_lines

          )

Plots scan ls at robot/laser pose x, y, th.

The scan is shifted by PM_LASER_Y.

Parameters:

	ls 	The laser scan to be plotted. The scan's pose is ignored.

	x 	The X coordinate of the pose where the scan should be drawn.

	y 	The Y coordinate of the pose where the scan should be drawn.

	th 	The orientation coordinate of the pose where the scan should be drawn.

	col 	The colour of the scan as "red", "green"... See dr_COLORS for more.

	diameter 	[cm] The drawn diameter of the measured points.

	connect_lines 	If true, measured point are connected with lines.

          void pm_plotTime4Thesis
          (
          PM_TYPE
           xt,

          PM_TYPE
           yt,

          PM_TYPE
           tht,

          int *
           iter,

          double *
           time

          )

Generates a convergence speed plot from previously saved result.

If you want to see the convergence speed, then uncomment the definition of PM_GENERATE_RESULTS, recompile, match a scan and run this function.

Only works if PM_GENERATE_RESULTS was enabled in the previous match as only then are results saved in a file which is read here.

Parameters:

	xt 	The true X coordinate where the solution should converge.

	yt 	The true Y coordinate where the solution should converge.

	tht 	[degrees] The true orientation where the solution should converge.

          void pm_preprocessScan
          (
          PMScan *
           ls
           )

Prepares a scan for scan matching.

Filters the scan using median filter, finds far away points and segments the scan.

Parameters:

	ls 	The scan to be preprocessed.

          PM_TYPE pm_psm
          (
          const PMScan *
           lsr,

          PMScan *
           lsa

          )

Match two laser scans using polar scan matching.

Minimizes the sum of square range residuals through changing lsa->rx, lsa->ry, lsa->th. The error is minimized by iterating a translation estimation step followed by an orientation search step.

PSM was not explicitly designed for laser scan matching based odometry where scans with small pose difference are matched with each other without any prior pose information. However when using PSM for this purpose, reduce the values of PM_MAX_ERROR, PM_WEIGHTING_FACTOR to reflect the small inter-scan motion. Also by reducing the value of PM_STOP_COND, larger matching accuracy can be achieved. The currently implemented error estimation functions are not useful for laser odometry error estimation.

Limitations: due to the nature of the association rule divergence in a slow rate may be experienced in rooms where there are not many features to constrain the solution in all directions. This can occur for examples in corridor-like environments including rooms where the room directly in front of the laser is outside of the range of the laser range finder.

Parameters:

	lsr 	The reference scan.

	lra 	The current scan.

          int pm_readScan
          (
          FILE *
           fin,

          PMScan *
           ls

          )

Reads one scan from file fin and stores it in ls.

Assumed data format:

 time[s] x[m] y[m] theta[rad]

 r0[cm]

 r1[cm]

 .

 .

 .

Parameters:

	fin 	Pointer to the file opened with pm_init().

	ls 	The read laser scan is returned here.

Returns:

Returns 0 on success, -1 if there are no more scans.

          void pm_save_scan
          (
          PMScan *
           act,

          const char *
           filename

          )

Saves scan in a text file.

Saves the scan in the format of:

 range[0] bad[0] segment[0]

 range[1] bad[1] segment[1]

 ...

 The aim is to enable quick scan loading in Octave using the "scan=load(filename)"; command

Parameters:

	act 	The scan to be saved.

	filenam 	The name of the file the scan is saved under.

          void pm_show_segmentation
          (
          const PMScan *
           ls
           )

Shows segmentation results by plotting segments with different colours.

Parameters:

	ls 	The scan to be plotted.

          void pm_unit_test
          (
          int
           matching_alg,

          bool
           interactive

          )

Performs unit tests on scan matching.

It will assert when compiled in debug mode. Currently the test are very basic (too high level). Should add more tests with time.

Parameters:

	matching_alg 	Specify the scan matching algorithm to be tested (PM_PSM, PM_ICP).

	interactive 	If true, graphically display results.

Variable Documentation

          PM_TYPE pm_co[PM_L_POINTS]

Contains the cosinus of each bearing.

          const PM_TYPE PM_D2R

Conversion factor for converting degrees to radians.

          PM_TYPE pm_fi[PM_L_POINTS]

Contains precomputed range bearings.

          const PM_TYPE PM_R2D

Conversion factor for converting radians to degrees.

          PM_TYPE pm_si[PM_L_POINTS]

Contains the sinus of each bearing.

<address style="text-align: right;">Generated on Tue Sep 21 10:19:15 2010 for PolarScanMatching(PSM) by

 1.5.8 </address>


text:
package org.dasein.cloud.platform;

import org.dasein.cloud.InternalException;
import org.dasein.cloud.ProviderContext;
import org.dasein.cloud.util.products.ProductReader;
import org.dasein.cloud.util.products.ProductReaderException;
import org.dasein.cloud.util.products.model.DatabaseProductDefinition;
import org.dasein.cloud.util.products.model.DatabaseProductProvider;
import org.dasein.cloud.util.products.model.DatabaseRegion;
import org.dasein.cloud.util.products.model.VmProductProvider;

import javax.annotation.Nonnull;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import static org.dasein.cloud.platform.DatabaseLicenseModel.*;

public class DatabaseProduct implements Serializable {
    private static final long serialVersionUID = -5535140342676937943L;

    private String               currency;
    private DatabaseEngine       engine;
    private DatabaseLicenseModel licenseModel;
    private boolean              highAvailability;
    private String               name;
    private String               productSize;
    private String               providerDataCenterId;
    private float                standardHourlyRate;
    private float                standardIoRate;
    private float                standardStorageRate;
    private int                  storageInGigabytes;

    public DatabaseProduct( String databaseSizeId ) {
        this(databaseSizeId, databaseSizeId);
    }

    public DatabaseProduct( String databaseSizeId, String databaseSizeName ) {
        this.productSize = databaseSizeId;
        this.name = databaseSizeName;
    }

    static public @Nonnull DatabaseProduct[] fromConfigurationFile(@Nonnull String pathToFile, @Nonnull ProviderContext context) throws InternalException {
        try {
            List<DatabaseProduct> products = new ArrayList<>();
            DatabaseProductProvider databaseProvider = ProductReader.readDatabaseProducts(pathToFile,
                    context.getCloud().getProviderName());

            List<org.dasein.cloud.util.products.model.DatabaseEngine> databaseEngines = databaseProvider.getEngines();

            for( org.dasein.cloud.util.products.model.DatabaseEngine databaseEngine : databaseEngines ) {
                for ( DatabaseRegion region : databaseEngine.getRegions() ) {
                    if( region.getName().equalsIgnoreCase( context.getRegionId()) ) {
                        for( org.dasein.cloud.util.products.model.DatabaseProduct databaseProduct : region.getProducts() ) {
                            DatabaseProduct product = new DatabaseProduct(databaseProduct.getName());
                            product.setEngine(DatabaseEngine.valueOf(databaseEngine.getName()));
                            product.setHighAvailability(databaseProduct.isHighAvailability());
                            product.setStandardHourlyRate(databaseProduct.getHourlyRate());
                            product.setStandardIoRate(databaseProduct.getIoRate());
                            product.setStandardStorageRate(databaseProduct.getStorageRate());
                            DatabaseLicenseModel lic = GENERAL_PUBLIC_LICENSE;
                            if( "included".equalsIgnoreCase(databaseProduct.getLicense())) {
                                lic = LICENSE_INCLUDED;
                            } else if( "byol".equalsIgnoreCase(databaseProduct.getLicense())) {
                                lic = BRING_YOUR_OWN_LICENSE;
                            } else if( "postgres".equalsIgnoreCase(databaseProduct.getLicense())) {
                                lic = POSTGRESQL_LICENSE;
                            }
                            product.setLicenseModel(lic);
                            product.setCurrency(databaseProduct.getCurrency());
                            DatabaseProductDefinition def = databaseProvider.findProductDefinition(databaseProduct.getName());
                            if( def != null) {
                                product.setName(String.format("%.2fGB RAM, %d CPU, %s Network Performance", def.getMemory(), def.getvCpus(), def.getNetworkPerformance()));
                            }
                            product.setStorageInGigabytes(databaseProduct.getMinStorage());
                            products.add(product);
                        }
                    }
                }
            }
            return products.toArray(new DatabaseProduct[products.size()]);
        }
        catch (ProductReaderException pre) {
            throw new InternalException("Unable to read product configuration file " + pathToFile, pre);
        }
        finally {}
    }

    public String getProductSize() {
        return productSize;
    }

    public void setProductSize( String databaseSizeId ) {
        this.productSize = databaseSizeId;
    }

    public String getName() {
        return name;
    }

    public void setName( String databaseSizeName ) {
        this.name = databaseSizeName;
    }

    public void setEngine( DatabaseEngine engine ) {
        this.engine = engine;
    }

    public DatabaseEngine getEngine() {
        return engine;
    }

    public DatabaseLicenseModel getLicenseModel() {
        return licenseModel;
    }

    public void setLicenseModel( DatabaseLicenseModel licenseModel ) {
        this.licenseModel = licenseModel;
    }

    public void setProviderDataCenterId( String providerDataCenterId ) {
        this.providerDataCenterId = providerDataCenterId;
    }

    public String getProviderDataCenterId() {
        return providerDataCenterId;
    }

    public void setStorageInGigabytes( int storageInGigabytes ) {
        this.storageInGigabytes = storageInGigabytes;
    }

    public int getStorageInGigabytes() {
        return storageInGigabytes;
    }

    public float getStandardHourlyRate() {
        return standardHourlyRate;
    }

    public void setStandardHourlyRate( float standardHourlyRate ) {
        this.standardHourlyRate = standardHourlyRate;
    }

    public float getStandardStorageRate() {
        return standardStorageRate;
    }

    public void setStandardStorageRate( float standardStorageRate ) {
        this.standardStorageRate = standardStorageRate;
    }

    public void setStandardIoRate( float standardIoRate ) {
        this.standardIoRate = standardIoRate;
    }

    public float getStandardIoRate() {
        return standardIoRate;
    }

    public void setCurrency( String currency ) {
        this.currency = currency;
    }

    public String getCurrency() {
        return currency;
    }

    public String toString() {
        return productSize;
    }

    public void setHighAvailability( boolean highAvailability ) {
        this.highAvailability = highAvailability;
    }

    public boolean isHighAvailability() {
        return highAvailability;
    }
}

redpajama_set_name: RedPajamaGithub


text:
||||
| --- | --- | --- |
| [← 3.1. GIVE-Toolbox](3.1-GIVE-Toolbox-usages.md) | [↑ Index](Readme.md) | [4.1. Bed Format →](4.1-bed.md) |

# MySQL commands for managing data in GIVE data source

To visualize new data with GIVE, you can add it to the MySQL-compatible data source.
***
*__NOTE:__ If you are not very familiar with SQL commands, it is recommended that you manage data used by GIVE using GIVE-Toolbox. Detailed manual of GIVE-Toolbox is shown in [3.1. GIVE-Toolbox usages for managing data in GIVE data source](3.1-GIVE-Toolbox-usages.md).*
***

## Table of Contents

*   [Creating a new reference genome for GIVE](#creating-a-new-reference-genome-for-give)
    *   [Creating a new reference genome database](#creating-a-new-reference-genome-database)
    *   [Creating a `cytoBandIdeo` table and populate it with data](#creating-a-cytobandideo-table-and-populate-it-with-data)
    *   [Adding an entry in `ref` table of `compbrowser`](#adding-an-entry-in-ref-table-of-compbrowser)
    *   [Creating track groups](#creating-track-groups)
    *   [Creating the track definition table](#creating-the-track-definition-table)
*   [Adding data](#adding-data)
    *   [Adding genomic span data (BED)](#adding-genomic-span-data-bed)
    *   [Adding linear tracks (bigWig)](#adding-linear-tracks-bigwig)
    *   [Adding interaction tracks](#adding-interaction-tracks)
*   [Property references](#property-references)
    *   [Reference table properties documentation](#reference-table-properties-documentation)
    *   [Database table properties documentation](#database-table-properties-documentation)

## Creating a new reference genome for GIVE
### Creating a new reference genome database

To visualize a new reference genome, GIVE only needs to know:
1.  The names of the species for this reference (Latin and common names are recommended but any name should work);
2.  Its chromosomal information, including names, sizes and the location of centromeres.

These are stored in two locations within the data source. First you need to create a database with __`your_reference_database`__:

CREATE DATABASE `<em><strong><your_reference_database></strong></em>`;

Also, make sure your __GIVE Database User__ has access to this database (if you haven't granted privilege for `*.*`):

GRANT SELECT, CREATE TEMPORARY TABLES ON `<em><strong><your_reference_database></strong></em>`.* TO `<em><strong><give_data_user></strong></em>`@'%';

### Creating a `cytoBandIdeo` table and populate it with data

Then you need to create a `cytoBandIdeo` table with chromosomal information in your reference database with the following columns:

| Column name | Type | Description |
| --- | --- | --- |
| `chrom` | `varchar` | Chromosome name |
| `chromStart` | `unsigned int` | The start coordinate of the band |
| `chromEnd` | `unsigned int` | The end coordinate of the band |
| `name` | `varchar` | Name of the band |
| `gieStain` | `varchar` | Giemsa Stain info, to identify bands, centromeres, etc. |

The SQL code to create this table is shown below:

CREATE TABLE `<em><strong><your_reference_database></strong></em>`.`cytoBandIdeo` (
  `chrom` varchar(255) NOT NULL,
  `chromStart` int(10) unsigned NOT NULL,
  `chromEnd` int(10) unsigned NOT NULL,
  `name` varchar(255) NOT NULL,
  `gieStain` varchar(255) NOT NULL,
  KEY `chrom` (`chrom`(23), `chromStart`)
) ENGINE=InnoDB;

The `cytoBandIdeo` table also needs to be populated by actual data. The following SQL command can be used if the file cytoBandIdeo is already on the server:

LOAD DATA LOCAL INFILE "<cytoBandIdeo_file_path>" INTO TABLE `<em><strong><your_reference_database></strong></em>`.`cytoBandIdeo`;

***
*__NOTE:__ The annotation files, including the `cytoBandIdeo` file for all references available on GIVE can be downloaded from UCSC or the following URL: <https://demo.give.genemo.org/annotations/>. Currently, `hg19`, `hg38`, `mm9` and `mm10` are available.*
***

### Adding an entry in `ref` table of `compbrowser`

After creating the table, you also need to add one entry in table `ref` of database `compbrowser`. Notice that the `browserActive` field needs to be set to `1` and in the `settings` field, the JSON string also has its `browserActive` attribute set as `true`. (You may want to try <http://www.objgen.com/json> to get a JSON string with ease.)

Please see

The SQL code is shown below:

INSERT INTO `compbrowser`.`ref` (
  `dbname`,
  `name`,
  `commonname`,
  `browserActive`,
  `settings`
) VALUES (
  '<your_reference_database>',
  '<species_name>',
  '<species_common_name>',
  1,
  '{
    "browserActive": true
  }'
);

### Creating track groups

Tracks in GIVE belong to track groups for better management and these groups need their place in the database. A `grp` table is required in the reference database to manage track groups with the following columns:

| Column name | Type | Description |
| --- | --- | --- |
| `name` | `varchar` | Group name |
| `label` | `varchar` | Description of the group |
| `priority` | `float` | Order for this group in the browser, less is upper |
| `defaultIsClosed` | `tinyint` | Whether the group will be closed by default, reserved |
| `singleChoice` | `tinyint` | Whether the group will only allow one track to be active at any time |

The SQL code to create this table is shown below:

CREATE TABLE `<em><strong><your_reference_database></strong></em>`.`grp` (
  `name` char(150) NOT NULL,
  `label` char(255) NOT NULL DEFAULT '',
  `priority` float NOT NULL DEFAULT '0',
  `defaultIsClosed` tinyint(2) DEFAULT NULL,
  `singleChoice` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`name`)
) ENGINE=InnoDB;

Individual track groups can be created by adding entries in the `grp` table, using the following SQL command:

INSERT INTO `<em><strong><your_reference_database></strong></em>`.`grp` VALUES (
  '<group_name>',
  '<group_description>',
  <the_priority_of_the_group>,
  <default_is_closed_value>,
  <whether_the_group_only_allows_one_choice>
);

### Creating the track definition table

Tracks themselves also need a place to store their annotation and data. This is achieved by creating a table named `trackDb` in the reference database with the following columns:

| Column name | Type | Description |
| --- | --- | --- |
| `tableName` | `varchar` | Name of the track table |
| `type` | `varchar` | Type of the track (__Important__) |
| `priority` | `float` | Order for the track (within group) |
| `url` | `longblob` | URL for the track, reserved |
| `html` | `longtext` | HTML description for the track, reserved |
| `grp` | `varchar` | Group of the track, should be the same as __*<group_name>*__ |
| `settings` | `longtext` | Detailed track settings, JSON format. See [Database table properties documentation](#database-table-properties-documentation) for details. |

The SQL code to create this table is shown below:

CREATE TABLE `<em><strong><your_reference_database></strong></em>`.`trackDb` (
  `tableName` varchar(150) NOT NULL,
  `type` varchar(255) NOT NULL,
  `priority` float NOT NULL,
  `url` longblob,
  `html` longtext,
  `grp` varchar(150) NOT NULL,
  `settings` longtext NOT NULL,
  PRIMARY KEY (`tableName`),
  FOREIGN KEY `group_id` (`grp`) REFERENCES
    `<em><strong><your_reference_database></strong></em>`.`grp` (`name`)
    ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;

After this step, GIVE will be able to display the new reference genome and also data tracks within it.

## Adding data

Adding tracks to GIVE database typically involves two steps:
1.  Create a table corresponding to the data type and populate it;
2.  Add an entry in the `trackDb` table with the metadata of the track.

### Adding genomic span data (BED)

The table for BED tracks needs to contain the following columns:

| Column name | Type | Description |
| --- | --- | --- |
| `name` | `varchar` | Name of the span (gene, transcript, etc.) |
| `chrom` | `varchar` | Chromosome name |
| `strand` | `char` | Strand of the span |
| `txStart` | `int` | Start coordinate of the span |
| `txEnd` | `int` | End coordinate of the span |
| `cdsStart` | `int` | Start coordinate of the 'thick' portion of the span |
| `cdsEnd` | `int` | End coordinate of the 'thick' portion of the span |
| `exonCount` | `int` | Number of exons in the span |
| `exonStarts` | `longblob` | The start coordinates of all exons, separated by comma |
| `exonEnds` | `longblob` | The end coordinates of all exons, separated by comma |
| `proteinID` | `varchar` | The ID of corresponding protein, only applies to gene tracks |
| `alignID` | `varchar` | The ID of alignment segments, only applies to gene tracks |

***
*__Note:__ This is different than BED12 format: 1) field order is slightly different; 2) the 9th and 10th columns represent the start and end coordinate of all the exons, instead of the start within the gene and length of the exon in BED12.*
***

The SQL command to create such a table is shown below:

CREATE TABLE `<em><strong><your_reference_database></strong></em>`.`<em><strong><track_table_name></strong></em>` (
  `name` varchar(255) NOT NULL DEFAULT '',
  `chrom` varchar(255) NOT NULL DEFAULT '',
  `strand` char(2) NOT NULL DEFAULT '',
  `txStart` int(10) unsigned NOT NULL DEFAULT '0',
  `txEnd` int(10) unsigned NOT NULL DEFAULT '0',
  `cdsStart` int(10) unsigned NOT NULL DEFAULT '0',
  `cdsEnd` int(10) unsigned NOT NULL DEFAULT '0',
  `exonCount` int(10) unsigned NOT NULL DEFAULT '0',
  `exonStarts` longblob NOT NULL,
  `exonEnds` longblob NOT NULL,
  `proteinID` varchar(40) NOT NULL DEFAULT '',
  `alignID` varchar(255) NOT NULL DEFAULT '',
  KEY `name` (`name`),
  KEY `chrom` (`chrom`(16),`txStart`),
  KEY `chrom_2` (`chrom`(16),`txEnd`),
  KEY `protein` (`proteinID`(16)),
  KEY `align` (`alignID`)
) ENGINE=InnoDB;

After the table is created, you can populate it with the actual data:

LOAD DATA LOCAL INFILE "<bed_data_file_path>" INTO TABLE `<em><strong><your_reference_database></strong></em>`.`<em><strong><track_table_name></strong></em>`;

The entry in the `trackDb` table can be added via the following SQL command:

INSERT INTO `<em><strong><your_reference_database></strong></em>`.`trackDb` VALUES (
  '<track_table_name>',
  'bed',
  1,
  NULL,
  NULL,
  'genes',                      -- Group name, should be the same as grp.name
  '{
    "group":"<group_name>",
    "longLabel":"<long_label>",
    "priority":1,
    "shortLabel":"<short_label>",
    "track":"<track_table_name>",
    "type":"bed",
    "visibility":"pack",
    "adaptive":true
  }'
);

### Adding linear tracks (bigWig)

The table for bigWig tracks only needs to contain the following column:

| Column name | Type | Description |
| --- | --- | --- |
| `fileName` | `varchar` | The path or URL of the bigWig file |

The SQL command to create such a table is shown below:

CREATE TABLE `<em><strong><your_reference_database></strong></em>`.`<em><strong><track_table_name></strong></em>` (
  `fileName` varchar(255) NOT NULL
) ENGINE=InnoDB;

After the table is created, you can populate it with the actual data:

INSERT INTO `<em><strong><your_reference_database></strong></em>`.`<em><strong><track_table_name></strong></em>` VALUES (
  '<bigWig_file_path>'
);

The entry in the `trackDb` table can be added via the following SQL command:

INSERT INTO `<em><strong><your_reference_database></strong></em>`.`trackDb` VALUES (
  '<track_table_name>',
  'bigWig',
  1,
  NULL,
  NULL,
  'genes',                      -- Group name, should be the same as grp.name
  '{
    "group":"<group_name>",
    "longLabel":"<long_label>",
    "priority":1,
    "shortLabel":"<short_label>",
    "track":"<track_table_name>",
    "type":"bigWig",
    "visibility":"full",
    "autoScale":false,
  }'
);

### Adding interaction tracks

Adding interaction tracks (in `interaction` format) is similar to adding `BED` or `GenePred` tracks. The table for interaction tracks needs to contain the following columns:

| Column name | Type | Description |
| --- | --- | --- |
| `ID` | `int` | ID of the interaction segment (can be generated by auto-increment) |
| `chrom` | `varchar` | Chromosome name |
| `Start` | `int` | Start coordinate of the span |
| `End` | `int` | End coordinate of the span |
| `linkID` | `int` | ID of the link (segments with the same linkID are linked together) |
| `value` | `float` | The value of the link |
| `dirFlag` | `tinyint` | The direction of the link (the link should go from the segment with `dirFlag` = 0 to the one with `dirFlag` = 1) if the link has direction, '-1' if the link does not have direction |

The SQL command to create such a table is shown below:

CREATE TABLE `<your_reference_database>`.`<em><strong><track_table_name></strong></em>` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `chrom` varchar(255) NOT NULL DEFAULT '',
  `start` int(10) unsigned NOT NULL DEFAULT '0',
  `end` int(10) unsigned NOT NULL DEFAULT '0',
  `linkID` int(10) unsigned NOT NULL DEFAULT '0',
  `value` float NOT NULL DEFAULT '0',
  `dirFlag` tinyint(4) NOT NULL DEFAULT '-1',
  PRIMARY KEY (`ID`),
  KEY `chrom` (`chrom`(16),`start`),
  KEY `chrom_2` (`chrom`(16),`end`),
  KEY `linkID` (`linkID`)
) ENGINE=InnoDB;

After the table is created, you can populate it with the actual data:

LOAD DATA LOCAL INFILE "<interaction_data_file_path>" INTO TABLE `<em><strong><your_reference_database></strong></em>`.`<em><strong><track_table_name></strong></em>`;

The entry in the `trackDb` table can be added via the following SQL command:

INSERT INTO `<em><strong><your_reference_database></strong></em>`.`trackDb` VALUES (
  '<track_table_name>',
  'interaction',
  1,
  NULL,
  NULL,
  'genes',                      -- Group name, should be the same as grp.name
  '{
    "group":"<group_name>",
    "longLabel":"<long_label>",
    "priority":1,
    "shortLabel":"<short_label>",
    "track":"<track_table_name>",
    "type":"interation",
    "visibility":"full",
    "thresholdPercentile": [
      <percentile_values_for_interaction_thresholds>
    ],
  }'
);

## Property references

For both references and tracks, the `settings` column in the corresponding
tables (`ref` table in `compbrowser` database for a reference, and `trackDb`
table in your reference database for a track.) includes some properties that
are available. This section lists some of the useful properties.

### Reference table properties documentation

Here are a brief description of the properties you may use for a reference in
the `settings` column of `ref` in the `compbrowser` database:

__browserActive__
> Type: `Boolean`
> Default: `false`
> Whether this reference will be enabled for the GIVE browser. If you would
> like to have this reference available, you will need to set this value to
> `true`.

__geneCoorTable__
> Type: `String`
> Default: `''`
> The database table for the gene name search function of `<gene-coor-input>`
> element. This table should have the columns shown below.
> | Column name | Type | Description |
> | --- | --- | --- |
> | `<gene-symbol-column>` | `VARCHAR` | Gene names/symbols (this can be a column of the table itself, or a column in the linked     table(s)). This value can be specified in `geneSymbolColumn` property, see below. |
> | `chrom` | `VARCHAR` | The name of the chromosome the gene is on |
> | `chromStart` | `INT` | Chromosomal start coordinates |
> | `chromEnd` | `INT` | Chromosomal end coordinates |

__geneSymbolColumn__
> Type: `String`
> Default: `'name'`
> The column for gene symbols in `geneCoorTable`.

__geneDescTable__
> Type: `String`
> Default: `''`
> When implementing gene name search function of `<gene-coor-input>`, this
> table can be used to provide the gene description in the search results. This
> table should have the columns shown below.
> | Column name | type | Description |
> | --- | --- | --- |
> | `<desc-symbol-column>` | `VARCHAR` | Gene symbols (corresponding to `<gene-symbol-column>` in `<gene-coordinate-table>`). This value can be specified in `descSymbolColumn` property, see below. |
> | `description` | `VARCHAR` | Gene description |

__descSymbolColumn__
> Type: `String`
> Default: `'Symbol'`
> The column for gene symbols in `geneDescTable`.

__aliasTable__
> Type: `String`
> Default: `''`
> When implementing gene name search function of `<gene-coor-input>`, this
> table can be used to link all the different aliases to their official symbol.
> (For example, `OCT3/4` to `POU5F1`.) This table should have the columns shown
> below.
> | Column name | type | Description |
> | --- | --- | --- |
> | `<alias-symbol-column>` | `VARCHAR` | gene symbols (corresponding to `<gene-symbol-column>` in `<gene-coordinate-table>`). This value can be specified in `aliasSymbolColumn` property, see below. |
> | `alias` | `VARCHAR` | Gene aliases, each alias shall occupy one row |
> | `isSymbol` | `BIT` | Indicating whether this alias is the same as `<gene-symbol-column>`, 1 if the alias is the same, 0 if not |

__aliasSymbolColumn__
> Type: `String`
> Default: `'Symbol'`
> The column for gene symbols in `aliasTable`.

### Database table properties documentation

Here are a brief description of the properties you may use in the `settings`
column of `trackDb` in your reference database:

__shortLabel__
> Type: `String`
> Default: `''`
> The short label shown by the track.

__longLabel__
> Type: `String`
> Default: `''`
> The long label providing more information. Reserved.

__visibility__
> Type: `enum` (`'full'`, `'pack'`, `'collapsed'`, `'dense'`, and `'hide'`)
> Default: `'hide'`
> The visibility of the track, values on the left are more visible/prominent.

__adaptive__
> Type: `Boolean`
> Default: `false`
> Whether the visibility will adapt to the height of the ending result. If the
> height exceeds certain threshold, the visibility will be degraded by one.

__dataType__, __cellType__, __trackFeature__, __labName__,
__groupDataType__, __groupFeature__, __groupSampleType__
> Type: `String`
> Default: `null`
> These are metadata of the tracks. Reserved for future features.

__thresholdPercentile__
> Type: `Array<Number>`
> Default: `null`
> A series of numbers defining the percentile of the data points in the track.
> This is used to color interaction graphs by their corresponding signal level.
> May be applied to other types of tracks in a future release.

||||
| --- | --- | --- |
| [← 3.1. GIVE-Toolbox](3.1-GIVE-Toolbox-usages.md) | [↑ Index](Readme.md) | [4.1. Bed Format →](4.1-bed.md) |


text:
inventory = ()

# treat the tuple as a condition
if not inventory:
    print("You are empty-handed.")

input("\nPress the enter key to continue.")

# create a tuple with some items
inventory = ("sword",
             "armor",
             "shield",
             "healing potion")

# print the tuple
print("\nThe tuple inventory is:")
print(inventory)

# print each element in the tuple
print("\nYour items:")
for item in inventory:
    print(item)

input("\n\nPress the enter key to exit.")


text:
package org.apache.cassandra.tools.nodetool;

import io.airlift.airline.Command;

/**
 * @deprecated use TableHistograms
 */
@Command(name = "cfhistograms", hidden = true, description = "Print statistic histograms for a given column family")
@Deprecated
public class CfHistograms extends TableHistograms
{
}


text:
<?php

namespace IPS\Helpers\Form;

/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
	header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
	exit;
}

/**
 * Stack input class for Form Builder
 */
class _Stack extends FormAbstract
{
	/**
	 * @brief	Default Options
	 */
	protected $defaultOptions = array(
		'stackFieldType'	=> 'Text',
        'removeEmptyValues' => TRUE,
        'maxItems'			=> NULL
	);

	/**
	 * Constructor: Store the form element to stack
	 *
	 * @see		\IPS\Helpers\Form\Abstract::__construct
	 * @param	string			$name					Name
	 * @param	mixed			$defaultValue			Default value
	 * @param	bool			$required				Required?
	 * @param	array			$options				Type-specific options
	 * @param	callback		$customValidationCode	Custom validation code
	 * @param	string			$prefix					HTML to show before input field
	 * @param	string			$suffix					HTML to show after input field
	 * @param	string			$id						The ID to add to the row
	 * @return	void
	 */
	public function __construct( $name, $defaultValue=NULL, $required=FALSE, $options=array(), $customValidationCode=NULL, $prefix=NULL, $suffix=NULL, $id=NULL )
	{
		call_user_func_array( 'parent::__construct', func_get_args() );

		\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery-ui.js', 'core', 'interface' ) );
		\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery-touchpunch.js', 'core', 'interface' ) );
		\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery.menuaim.js', 'core', 'interface' ) );

		/* Test for javascript disabled add stack */
		if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
		{
			if ( ( \IPS\Request::i()->valueFromArray('form_remove_stack') !== NULL OR isset( \IPS\Request::i()->form_add_stack ) ) and \IPS\Request::i()->csrfKey === \IPS\Session::i()->csrfKey )
			{
				$this->reloadForm = true;
			}
		}
	}

	/**
	 * Get HTML
	 *
	 * @return	string
	 */
	public function html()
	{
		$fields		= array();
		$classType	= mb_strpos( $this->options['stackFieldType'], '\\' ) === FALSE ? ( "\\IPS\\Helpers\\Form\\" . $this->options['stackFieldType'] ) : $this->options['stackFieldType'];
		$remove     = \IPS\Request::i()->valueFromArray('form_remove_stack');

		/* The JS fallback needs a unique key for the field to remove */
		$remove = ( is_array( $remove ) ) ? key( $remove ) : null;

		if( count($this->value) )
		{
			foreach( $this->value as $k => $v )
			{
				$class = ( new $classType( $this->name . '[' . count($fields) . ']', $v, FALSE, $this->options, $this->customValidationCode, $this->prefix, $this->suffix, $this->htmlId  . '_' . count($fields) ) );
				$html = $class->html();

				if( !\IPS\Login::compareHashes( $remove, md5( $html ) ) )
				{
					$fields[] = $html;
				}
			}
		}
		else
		{
			$class = ( new $classType( $this->name . '[0]', NULL, FALSE, $this->options, $this->customValidationCode, $this->prefix, $this->suffix, $this->htmlId  . '_' . count($fields) ) );
			$html = $class->html();

			if( !\IPS\Login::compareHashes( $remove, md5( $html ) ) )
			{
				$fields[] = $html;
			}
		}

		/* We hit the add stack button with JS disabled */
		if ( $this->reloadForm === TRUE AND $remove === NULL )
		{
			$class = ( new $classType( $this->name . '[]', NULL, FALSE, $this->options, $this->customValidationCode, $this->prefix, $this->suffix, $this->htmlId  . '_' . count($fields) ) );
			$html     = $class->html();
			$fields[] = $html;
		}

		return \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->stack( $this->name, $fields, $this->options );
	}

	/**
	 * Format Value
	 *
	 * @return	mixed
	 */
	public function formatValue()
	{
		$values		= array();
		$classType	= mb_strpos( $this->options['stackFieldType'], '\\' ) === FALSE ? ( "\\IPS\\Helpers\\Form\\" . $this->options['stackFieldType'] ) : $this->options['stackFieldType'];
		$name		= $this->name;

		if( mb_substr( $name, 0, 8 ) !== '_new_[x]' and isset( \IPS\Request::i()->$name ) )
		{
			if( is_array( \IPS\Request::i()->$name ) AND count( \IPS\Request::i()->$name ) )
			{
				foreach( \IPS\Request::i()->$name as $k => $v )
				{
					$class = ( new $classType( $this->name . '[]', $v, FALSE, $this->options, $this->customValidationCode, $this->prefix, $this->suffix, $this->htmlId ) );
					$values[]	= $class->value;
				}
			}

            return ( $this->options['removeEmptyValues'] ) ? array_filter( $values ) : $values;
		}
		else if ( is_array( $this->value ) AND count( $this->value ) )
		{
			foreach( $this->value as $k => $v )
			{
				$class = ( new $classType( $this->name . '[]', $v, FALSE, $this->options, $this->customValidationCode, $this->prefix, $this->suffix, $this->htmlId ) );
				$values[]	= $class->value;
			}

			return ( $this->options['removeEmptyValues'] ) ? array_filter( $values ) : $values;
		}
		else
		{
			return array();
		}
	}

	/**
	 * Validate
	 *
	 * @throws	\InvalidArgumentException
	 * @return	TRUE
	 */
	public function validate()
	{
		if ( empty( $this->value ) and $this->required )
		{
			throw new \InvalidArgumentException('form_required');
		}

		if ( $this->options['maxItems'] !== NULL and count( $this->value ) > $this->options['maxItems'] )
		{
			throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'form_tags_max', FALSE, array( 'pluralize' => array( $this->options['maxItems'] ) ) ) );
		}

		parent::validate();
	}
}


text:
import type { AppProps } from 'next/app'

import 'normalize.css/normalize.css'
import '../styles/new.scss'
import 'bootstrap/dist/css/bootstrap-grid.css'
import 'bootstrap/dist/css/bootstrap-utilities.css'
import 'inter-ui/inter.css'
import '../styles/globals.scss'

export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}


text:
Using OpenCV with Eclipse (plugin CDT) {#tutorial_linux_eclipse}
======================================

Prerequisites
-------------
Two ways, one by forming a project directly, and another by CMake Prerequisites
-#  Having installed [Eclipse](http://www.eclipse.org/) in your workstation (only the CDT plugin for
    C/C++ is needed). You can follow the following steps:
    -   Go to the Eclipse site
    -   Download [Eclipse IDE for C/C++
        Developers](http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliossr2) .
        Choose the link according to your workstation.
-#  Having installed OpenCV. If not yet, go @ref tutorial_linux_install "here".

Making a project
----------------

-#  Start Eclipse. Just run the executable that comes in the folder.
-#  Go to **File -\> New -\> C/C++ Project**

    ![](images/a0.png)

-#  Choose a name for your project (i.e. DisplayImage). An **Empty Project** should be okay for this
    example.

    ![](images/a1.png)

-#  Leave everything else by default. Press **Finish**.
-#  Your project (in this case DisplayImage) should appear in the **Project Navigator** (usually at
    the left side of your window).

    ![](images/a3.png)

-#  Now, let's add a source file using OpenCV:
    -   Right click on **DisplayImage** (in the Navigator). **New -\> Folder** .

        ![](images/a4.png)

    -   Name your folder **src** and then hit **Finish**
    -   Right click on your newly created **src** folder. Choose **New source file**:
    -   Call it **DisplayImage.cpp**. Hit **Finish**

        ![](images/a7.png)

-#  So, now you have a project with a empty .cpp file. Let's fill it with some sample code (in other
    words, copy and paste the snippet below):
    @code{.cpp}
    #include <opencv2/opencv.hpp>

    using namespace cv;

    int main( int argc, char** argv )
    {
      Mat image;
      image = imread( argv[1], 1 );

      if( argc != 2 || !image.data )
        {
          printf( "No image data \n" );
          return -1;
        }

      namedWindow( "Display Image", WINDOW_AUTOSIZE );
      imshow( "Display Image", image );

      waitKey(0);

      return 0;
    }
    @endcode
-#  We are only missing one final step: To tell OpenCV where the OpenCV headers and libraries are.
    For this, do the following:

    -   Go to **Project--\>Properties**
    -   In **C/C++ Build**, click on **Settings**. At the right, choose the **Tool Settings** Tab.
        Here we will enter the headers and libraries info:
        -#  In **GCC C++ Compiler**, go to **Includes**. In **Include paths(-l)** you should
            include the path of the folder where opencv was installed. In our example, this is
            /usr/local/include/opencv.

            ![](images/a9.png)

            @note If you do not know where your opencv files are, open the **Terminal** and type:
            @code{.bash}
            pkg-config --cflags opencv
            @endcode
            For instance, that command gave me this output:
            @code{.bash}
            -I/usr/local/include/opencv -I/usr/local/include
            @endcode

        -#  Now go to **GCC C++ Linker**,there you have to fill two spaces:

            First in **Library search path (-L)** you have to write the path to where the opencv libraries
            reside, in my case the path is: :

                /usr/local/lib

            Then in **Libraries(-l)** add the OpenCV libraries that you may need. Usually just the 4 first
            on the list below are enough (for simple applications) . In my case, I am putting all of them
            since I plan to use the whole bunch:

            opencv_core opencv_imgproc opencv_imgcodecs opencv_highgui opencv_ml opencv_videoio opencv_video opencv_features2d
            opencv_calib3d opencv_objdetect opencv_flann

            ![](images/a10.png)

            If you don't know where your libraries are (or you are just psychotic and want to make sure
            the path is fine), type in **Terminal**:
            @code{.bash}
            pkg-config --libs opencv
            @endcode
            My output (in case you want to check) was:
            @code{.bash}
            -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_videoio -lopencv_imgcodecs -lopencv_flann
            @endcode
            Now you are done. Click **OK**

-   Your project should be ready to be built. For this, go to **Project-\>Build all**

    In the Console you should get something like

    ![](images/a12.png)

    If you check in your folder, there should be an executable there.

Running the executable
----------------------

So, now we have an executable ready to run. If we were to use the Terminal, we would probably do
something like:
@code{.bash}
cd <DisplayImage_directory>
cd src
./DisplayImage ../images/HappyLittleFish.png
@endcode
Assuming that the image to use as the argument would be located in
\<DisplayImage_directory\>/images/HappyLittleFish.png. We can still do this, but let's do it from
Eclipse:

-#  Go to **Run-\>Run Configurations**
-#  Under C/C++ Application you will see the name of your executable + Debug (if not, click over
    C/C++ Application a couple of times). Select the name (in this case **DisplayImage Debug**).
-#  Now, in the right side of the window, choose the **Arguments** Tab. Write the path of the image
    file we want to open (path relative to the workspace/DisplayImage folder). Let's use
    **HappyLittleFish.png**:

    ![](images/a14.png)

-#  Click on the **Apply** button and then in Run. An OpenCV window should pop up with the fish
    image (or whatever you used).

    ![](images/a15.jpg)

-#  Congratulations! You are ready to have fun with OpenCV using Eclipse.

### V2: Using CMake+OpenCV with Eclipse (plugin CDT)

Say you have or create a new file, *helloworld.cpp* in a directory called *foo*:
@code{.cpp}
#include <opencv2/opencv.hpp>
using namespace cv;

int main ( int argc, char **argv )
{
  Mat img(480, 640, CV_8U);
  putText(img, "Hello World!", Point( 200, 400 ), FONT_HERSHEY_SIMPLEX | FONT_ITALIC, 1.0, Scalar( 255, 255, 0 ));
  imshow("My Window", img);
  waitKey();
  return 0;
}
@endcode
-#  Create a build directory, say, under *foo*: mkdir /build. Then cd build.
-#  Put a `CmakeLists.txt` file in build:
@code{.bash}
PROJECT( helloworld_proj )
FIND_PACKAGE( OpenCV REQUIRED )
ADD_EXECUTABLE( helloworld helloworld.cxx )
TARGET_LINK_LIBRARIES( helloworld \f${OpenCV_LIBS} )
@endcode
-#  Run: cmake-gui .. and make sure you fill in where opencv was built.
-#  Then click configure and then generate. If it's OK, **quit cmake-gui**
-#  Run `make -j4` (the -j4 is optional, it just tells the compiler to build in 4 threads). Make
    sure it builds.
-#  Start eclipse. Put the workspace in some directory but **not** in foo or `foo\build`
-#  Right click in the Project Explorer section. Select Import And then open the C/C++ filter.
    Choose *Existing Code* as a Makefile Project.
-#  Name your project, say *helloworld*. Browse to the Existing Code location `foo\build` (where
    you ran your cmake-gui from). Select *Linux GCC* in the *"Toolchain for Indexer Settings"* and
    press *Finish*.
-#  Right click in the Project Explorer section. Select Properties. Under C/C++ Build, set the
    *build directory:* from something like `${workspace_loc:/helloworld}` to
    `${workspace_loc:/helloworld}/build` since that's where you are building to.

    -#  You can also optionally modify the Build command: from make to something like
        `make VERBOSE=1 -j4` which tells the compiler to produce detailed symbol files for debugging and
        also to compile in 4 parallel threads.

-#  Done!


text:
import { Component, forwardRef } from '@angular/core';
import { Conduit, ConduitZone, ConduitZoneComponent } from '@ux-aspects/ux-aspects';
import { BehaviorSubject } from 'rxjs';

@Component({
    selector: 'uxd-components-conduit-toolbar',
    templateUrl: './toolbar.component.html',
    styleUrls: ['./toolbar.component.less'],
    providers: [ConduitZone]
})
export class ComponentsConduitToolbarComponent extends ConduitZoneComponent {

    zoneId: string = 'toolbar-zone';
    acceptsInput: boolean | string[] = true;
    producesOutput: boolean = true;

    // We want to trigger this every time it changes - even if it emitting is the same value
    @Conduit(forwardRef(() => ({ id: 'search', acceptsInput: false, changeDetection: () => false })) as any)
    search = new BehaviorSubject('');

    @Conduit(forwardRef(() => ({ id: 'show-zones' })) as any)
    showZones = new BehaviorSubject(false);

    clear(): void {
        this.search.next('');
    }

    toggle(): void {
        this.showZones.next(!this.showZones.value);
    }
}