• About Us
  • Blog
  • Basket
  • Account
  • Sign In


How to use signatures to filter device data by specific properties and values

Published on Wednesday, September 16, 2015

How to use signatures to filter device data by specific properties and values

Get the most out of your 51Degrees data file using Java API

Did you know that you can use the 51Degrees device data file not only for device detection, but also for enhancing the report generating tools, enhancing the analytics data and exposing parts of data to improve client experience? This article demonstrates how to use the signature entities from the 51Degrees data file to produce a subset of signatures based on one or more property.

The idea is simple: start with a full set of signatures and apply a filter until you only have the subset that matches all of the specified parameters. The example source code includes a test run function that starts by removing signatures where HardwareVendor is not 'Samsung'. Then a filter is applied to only leave signatures where the IsSmartPhone property is set to 'true'. Finally the list is filtered yet again to leave only the signatures where the PlatformName is 'Android'. The remaining signatures in the list correspond to Samsung smart phones that run on Android.


These are just some of the examples of where this functionality will prove useful.

  • An ad-tech company could allow clients to fine-tune their ad placement. For example: there is very little benefit for an online store that sells Windows phone accessories to display ads to users on other phones. Allowing customers to target specific devices or operating systems will benefit both.
  • A mobile analytics company could use the data to help identify the trends in device popularity or track the popularity of a particular device characteristic like the screen size.
  • When generating usage reports it is useful to be able to select statistics by a specific property or a combination of properties. While the report generation could be automated, selecting the properties to use for the report should be left to the end user. Better yet, also allow to select the value for the property. The information generated could prove invaluable for analytics.

Filtering devices

Firstly you need to create a Provider object you can use to access the data file entities. For more information on the structure of the Pattern data file please see 'Pattern Data Model'.

Provider provider;
 * Default constructor.
 * @param fiftyOneDataFile path to the 51Degrees data file.
public SequentialListGenerator(String fiftyOneDataFile) {
  try {
    //Use memory mode for this as Stream will take considerably longer.
    this.provider = new Provider(MemoryFactory.create(fiftyOneDataFile, false));
  } catch (IOException ex) {
	.log(Level.SEVERE, null, ex);

In the snippet above the Provider object gets instantiated with the dataset created by the memory factory. Memory factory reads the entire dataset into memory which makes it faster than stream factory which only loads the headers but uses the actual data file to retrieve entities.

Create a copy of the signatures list that will be used to remove the irrelevant signatures. A signature is the base entity that has a rank and profiles assigned to it. Through the profiles you can access the values and properties associated with those profiles.

//The original list of all the Signatures.
ArrayList<Signature> sortedSignatures;

 * Copies Signatures in to a list.
public final void readSignaturesToRanked() {
  this.sortedSignatures = new ArrayList<Signature>();
  for (Signature s : provider.dataSet.getSignatures()) {

If you plan to reuse the list or require a filter reset functionality you might want to copy the list of signatures and perform filtering on the copy of the list.

The actual filtering is done by traversing the list of signatures and adding each signature to the temporary list if the value of the property used to filter equals the value required. The temporary list then gets swapped with the current signature list leaving only signatures where the specified property has the specified value.

public void filterBy(String propertyName, String propertyValue) throws IOException {
  ArrayList<Signature> temp = new ArrayList<Signature>();
  for (Signature s : this.filterSet) {
    if (s.getValues(propertyName).toString().equals(propertyValue)) {
  this.filterSet = temp;

With each call of the filter function there will be less signatures in the list.

Filtering by signature rank

Each signature has a rank assigned to it. Rank indicates how often this signature is encountered in the wild. The lower the rank the more popular the signature is. You can use this information to remove the unlikely/unpopular signatures. For example: it is entirely possible to run an Android OS on an iPhone hardware but there is only a handful of people who does this therefore such cases can safely be ignored. Removing the signatures with the higher rank means the result is more accurate and relevant in some cases.

There are different algorithms to decide which rank should be the threshold in each particular case. The following example allows user to specify the level of threshold as a percentage. An alternative would be to use the mean or median value and remove ranks that exceed it.

public void trimRank(int thresholdPercentage) {
  //Initially first rank is both highest and lowest.
  int smallest = this.filterSet.get(0).getRank();
  int largest = this.filterSet.get(0).getRank();
  //First pass.
  //Find min and max.
  for (int i = 0; i < this.filterSet.size(); i++) {
    if (smallest > this.filterSet.get(i).getRank()) {
      smallest = this.filterSet.get(i).getRank();
    if (largest < this.filterSet.get(i).getRank()) {
      largest = this.filterSet.get(i).getRank();
  //Chop off the signatures that are below the threshold.
  int threshold = (largest - smallest) / 100 * thresholdPercentage;
  //Second pass.
  //only leave signatures with rank below the threshold.
  //the lower the rank the more popular the device.
  ArrayList<Signature> temp = new ArrayList<Signature>();
  for (Signature s : this.filterSet) {
    if (s.getRank() < threshold) {
  this.filterSet = temp;

In the snippet above the signature list is traversed twice. First time to find the largest and smallest signature rank. Second time to remove any signatures that are in the subset where signatures are X percent larger than the threshold. An alternative would be to sort the list based on signature rank and then traverse it removing the signatures.

Complete source code

You can download the complete source code from pastebin. The latest 51Degrees Java API can be downloaded here.

Remember that you need a 51Degrees device data file. You can download the latest Lite data file from github or try out our Premium or Enterprise data file by signing up for the evaluation.

Comments (0)


Other posts by Mike
Contact author



.NET 2013 2014 4G 51Degrees 5G A.C.Roma A7 ABI Acer Adtech Affiliate Marketing Afilias Alcatel Amazon AMP Analysis Analytics Android Android 5.0 Lollipop Android Kitkat Android Lollipop Android Media Stick Apache API Apple Apple TV Archos Asha Asian Market ASP.NET Asus Australia Big Data Black Friday Blackberry Blink Browser C C# Case Study CeBIT CES Chrome Cloud CMS combinations Comparison Competition CoolPad COTW Cron CSS3 Data Data Blog Data File Data Model Daydream Denver Design Desire Eye Desktop Detection Developers Device Device Data Device Detection Device Intelligence Device Popularity Device property Device Types Device Use DeviceAtlas Display dmexco DoCoMo Doogee DotNetNuke Download Drupal Email EReader E-Reader Ericsson Evaluation Event Examples EXPLAY Rio Facebook feature Firefox Firefox OS Fly Foundation Framework France Galaxy S3 Galaxy S5 Galaxy Tab A Galaxy Tab A 8.0 Galaxy Tab A 9.7 Germany git repositories Global Google Google Daydream GSMA HAProxy Hardware Hisense HTC HTC ONE MAX HTC OS HTML5 HTTP HTTP Headers Huawei HUAWEI. UPDATE HUDL Huwaei IBC Icemobile Prime 4.0 IE IFA IIS Image Optimiser Image Optimizer India Infographic Ingeniux Internet usage iOS iOS 7 iOS 8 ipad iPhone iPhone 6 IsEmailBrowser IsWebApp Italy Japan Java Javascript Jolla Kentico Keynote Kindle Kindle Fire Kindle Fire HD Leagoo Lenovo LG Location Log File Analysis LTE Lumia m.dot macOS Map Memory Meta Data Mi 4S Micromax Microsoft Miia Style Mobile Mobile Analysis Mobile Analytics Mobile Devices Mobile Marketing Mixer Module Motorola MVC4 MWC MWC 2017 MWC16 MyPhone Native Native Apps NET New Release News News Letter Nexus Nexus 6 Nexus 9 NFC NGINX Nokia Nokia 3310 Non-Mobile NVIDIA Omate On7 OnePlus 5 Opera Opera Mini Operating System Optimisation OS OSX 10.10 OTA Panasonic Patent PC Pebble Performance phablet phone PHP Poland Presentation Press Release Price Band PRIV programmatic PS4 Publishers Python QMobile QR Codes Redirection Research Reseller Responsive Images Responsive web design RESS Review reviews RIM Ringmark RTB RWD Safari Samsung Scala ScientiaMobile Screen Screen resolution Screen Size SEO Server Server-side optimisation Set Box Set Top Box Sharepoint Shark 1 SHIFT phones Sitecore Sitecore version 9 SLUSH Smart TV Smartphone Smartphones Smartwatches Snapdragon Sony Sony Xperia Spain Swedish Beers Symbian Tablet Tablets Tesco Testing Tips Top 5 TOTW Tutorial TV UDS UK Umbraco Update updates US User Agent UserAgent User-Agent Vendors Version 3 Video VoLTE VR Wearable Web Web Apps Web content management WebKit WebMatrix White Paper Widgets Widnows WiFi Wiko Wileyfox Windows Windows Phone WURFL Xbox XBox One Xiaomi Xperia Xperia z Yosemite Z10 ZenFon 2 ZOPO ZTE