extensions/no.uib.cbu.base.magetabexport/trunk/src/main/java/no/uib/cbu/base/magetabexport/SDRF.java

Code
Comments
Other
Rev Date Author Line
1474 29 Nov 11 pawels 1 /*******************************************************************************
1474 29 Nov 11 pawels 2  * Copyright (c) 2011 The Norwegian Microarray Consortium.
1474 29 Nov 11 pawels 3  * All rights reserved. This program and the accompanying materials
1474 29 Nov 11 pawels 4  * are made available under the terms of the GNU Public License v3.0
1474 29 Nov 11 pawels 5  * which accompanies this distribution, and is available at
1474 29 Nov 11 pawels 6  * http://www.gnu.org/licenses/gpl-3.0.html
1474 29 Nov 11 pawels 7  * 
1474 29 Nov 11 pawels 8  * Contributors:
1474 29 Nov 11 pawels 9  *     The Norwegian Microarray Consortium - initial API and implementation
1474 29 Nov 11 pawels 10  ******************************************************************************/
1474 29 Nov 11 pawels 11 package no.uib.cbu.base.magetabexport;
1474 29 Nov 11 pawels 12
1474 29 Nov 11 pawels 13 import java.util.ArrayList;
1474 29 Nov 11 pawels 14 import java.util.HashSet;
1474 29 Nov 11 pawels 15 import java.util.Hashtable;
1474 29 Nov 11 pawels 16 import java.util.List;
1474 29 Nov 11 pawels 17
1474 29 Nov 11 pawels 18 public class SDRF {
1474 29 Nov 11 pawels 19                 
1474 29 Nov 11 pawels 20   private String DELIMITER = MageTabExporterSettings.DELIMITER;;
1474 29 Nov 11 pawels 21
1474 29 Nov 11 pawels 22   /*
1474 29 Nov 11 pawels 23    *  Constant header values
1474 29 Nov 11 pawels 24    */
1474 29 Nov 11 pawels 25   private final String SOURCE_NAME = "Source Name";
1474 29 Nov 11 pawels 26   private final String SAMPLE_NAME = "Sample Name";
1474 29 Nov 11 pawels 27   private final String EXTRACT_NAME = "Extract Name";
1474 29 Nov 11 pawels 28   private final String LABELED_EXTRACT_NAME = "Labeled Extract Name";
1474 29 Nov 11 pawels 29   private final String HYBRIDIZATION_NAME = "Hybridization Name";
1474 29 Nov 11 pawels 30   private final String SCAN_NAME = "Scan Name";
1474 29 Nov 11 pawels 31   private final String ARRAY_DATA_FILE = "Array Data File";
1474 29 Nov 11 pawels 32   private final String NORMALIZATION_NAME = "Normalization Name";
1474 29 Nov 11 pawels 33   private final String DERIVED_ARRAY_DATA_MATRIX_FILE = "Derived Array Data Matrix File";
1474 29 Nov 11 pawels 34   
1474 29 Nov 11 pawels 35   private final String CHARACTERISTICS = "Characteristics";
1474 29 Nov 11 pawels 36   private final String TERM_SOURCE_REF = "Term Source REF";
1474 29 Nov 11 pawels 37   private final String PROTOCOL_REF = "Protocol REF";
1474 29 Nov 11 pawels 38   private final String PARAMETER_VALUE = "Parameter Value";
1474 29 Nov 11 pawels 39   private final String ARRAY_DESIGN_REF = "Array Design REF";
1474 29 Nov 11 pawels 40   
1474 29 Nov 11 pawels 41   private final String FACTOR_VALUE = "Factor Value";
1474 29 Nov 11 pawels 42   private final String MATERIAL_TYPE = "Material Type";
1474 29 Nov 11 pawels 43   private final String LABEL = "Label";
1474 29 Nov 11 pawels 44   
1474 29 Nov 11 pawels 45   private List<SDRFEntry> entries;
1474 29 Nov 11 pawels 46   
1474 29 Nov 11 pawels 47   private String header;
1474 29 Nov 11 pawels 48   
1474 29 Nov 11 pawels 49   public SDRF() {
1474 29 Nov 11 pawels 50     entries = new ArrayList<SDRFEntry>();
1474 29 Nov 11 pawels 51   }
1474 29 Nov 11 pawels 52   
1474 29 Nov 11 pawels 53   
1474 29 Nov 11 pawels 54   public List<SDRFEntry> getSDRFEntries() {
1474 29 Nov 11 pawels 55     return entries;
1474 29 Nov 11 pawels 56   }
1474 29 Nov 11 pawels 57
1474 29 Nov 11 pawels 58   
1474 29 Nov 11 pawels 59   public void addSDRFEntry(SDRFEntry entry) throws MageTabException {
1474 29 Nov 11 pawels 60     if (entry == null) { return; }
1474 29 Nov 11 pawels 61     
1474 29 Nov 11 pawels 62     if (!entries.isEmpty()) { 
1474 29 Nov 11 pawels 63       // if this is not the first entry, check if number of columns matches previous entries
1474 29 Nov 11 pawels 64       checkColumns(entry);
1474 29 Nov 11 pawels 65     }
1474 29 Nov 11 pawels 66
1474 29 Nov 11 pawels 67     entries.add(entry);
1474 29 Nov 11 pawels 68   }
1474 29 Nov 11 pawels 69
1474 29 Nov 11 pawels 70
1474 29 Nov 11 pawels 71   private void checkColumns(SDRFEntry entry) throws MageTabException {
1474 29 Nov 11 pawels 72     
1474 29 Nov 11 pawels 73     Hashtable<ItemInfo.TYPE, ItemInfo> newEntryItems = entry.getItems();
1474 29 Nov 11 pawels 74     Hashtable<ItemInfo.TYPE, ItemInfo> firstEntryItems = entries.get(0).getItems();
1474 29 Nov 11 pawels 75     
1474 29 Nov 11 pawels 76     
1474 29 Nov 11 pawels 77     /*
1474 29 Nov 11 pawels 78      * iterate over item types and add 'placeholder' items and characteristics
1474 29 Nov 11 pawels 79      * wherever its appropriate 
1474 29 Nov 11 pawels 80      */ 
1474 29 Nov 11 pawels 81     for (ItemInfo.TYPE type : ItemInfo.TYPE.values()) {
1474 29 Nov 11 pawels 82
1474 29 Nov 11 pawels 83       /* 
1474 29 Nov 11 pawels 84        * Check all items and try to fix sources, samples & pooled items
1474 29 Nov 11 pawels 85        * by inserting placeholders if an item is missing
1474 29 Nov 11 pawels 86        */
1474 29 Nov 11 pawels 87       if (MageTabExporterSettings.FILL_MISSING_VALUES && 
1474 29 Nov 11 pawels 88         (type.equals(ItemInfo.TYPE.SOURCE) || type.equals(ItemInfo.TYPE.SAMPLE) ||
1474 29 Nov 11 pawels 89           type.equals(ItemInfo.TYPE.POOLED_SAMPLE) || type.equals(ItemInfo.TYPE.POOLED_EXTRACT) ||
1474 29 Nov 11 pawels 90           type.equals(ItemInfo.TYPE.POOLED_LABELED_EXTRACT))) {    
1474 29 Nov 11 pawels 91         
1474 29 Nov 11 pawels 92         /*
1474 29 Nov 11 pawels 93          * Fix this entry or previous entries by adding an empty item.
1474 29 Nov 11 pawels 94          * Empty/NA fields are allowed only for these two types.
1474 29 Nov 11 pawels 95          */        
1474 29 Nov 11 pawels 96
1474 29 Nov 11 pawels 97         ProtocolInfo.TYPE pType = type.equals(ItemInfo.TYPE.SAMPLE) ? 
1474 29 Nov 11 pawels 98             ProtocolInfo.TYPE.SAMPLING : ProtocolInfo.TYPE.POOLING;
1474 29 Nov 11 pawels 99             
1474 29 Nov 11 pawels 100         if (!newEntryItems.containsKey(type) && firstEntryItems.containsKey(type)) {
1474 29 Nov 11 pawels 101           // the new entry is missing an item that all previous have
1474 29 Nov 11 pawels 102           ItemInfo item = new ItemInfo(type, null);
1474 29 Nov 11 pawels 103           if (!type.equals(ItemInfo.TYPE.SOURCE)) { 
1474 29 Nov 11 pawels 104             item.setProtocol(new ProtocolInfo(pType, null, null)); 
1474 29 Nov 11 pawels 105           }
1474 29 Nov 11 pawels 106           entry.addItem(item);
1474 29 Nov 11 pawels 107         } else if (newEntryItems.containsKey(type) && !firstEntryItems.containsKey(type)) {
1474 29 Nov 11 pawels 108           //   previous entries miss an item the new one has
1474 29 Nov 11 pawels 109           for (SDRFEntry e : entries) {
1474 29 Nov 11 pawels 110             ItemInfo item = new ItemInfo(type, null);
1474 29 Nov 11 pawels 111             if (!type.equals(ItemInfo.TYPE.SOURCE)) { 
1474 29 Nov 11 pawels 112               item.setProtocol(new ProtocolInfo(pType, null, null)); 
1474 29 Nov 11 pawels 113             }
1474 29 Nov 11 pawels 114             e.addItem(item);
1474 29 Nov 11 pawels 115           }
1474 29 Nov 11 pawels 116         } else if (!newEntryItems.containsKey(type) && !firstEntryItems.containsKey(type)) {
1474 29 Nov 11 pawels 117           // neither entry has an item of this type - move to the next item type
1474 29 Nov 11 pawels 118           continue;
1474 29 Nov 11 pawels 119         } else {
1474 29 Nov 11 pawels 120           // both have an item of this type - check for missing protocols & characteristics
1474 29 Nov 11 pawels 121         }
1474 29 Nov 11 pawels 122         
1474 29 Nov 11 pawels 123       } else {  //throw an exception, or ignore if none of the entries has the item
1474 29 Nov 11 pawels 124         
1474 29 Nov 11 pawels 125         if ((!newEntryItems.containsKey(type) && firstEntryItems.containsKey(type)) || 
1474 29 Nov 11 pawels 126           (newEntryItems.containsKey(type) && !firstEntryItems.containsKey(type))) {
1474 29 Nov 11 pawels 127           //   either existing entries have the item and the new one has not, or the opposite
1474 29 Nov 11 pawels 128           throw MageTabException.newMissingItemException(type);
1474 29 Nov 11 pawels 129         } else if (!newEntryItems.containsKey(type) && !firstEntryItems.containsKey(type)) {
1474 29 Nov 11 pawels 130           // neither entry has an item of this type - move to the next item type
1474 29 Nov 11 pawels 131           continue;
1474 29 Nov 11 pawels 132         } else { 
1474 29 Nov 11 pawels 133           // both have an item of this type - check for missing protocols & characteristics
1474 29 Nov 11 pawels 134         }
1474 29 Nov 11 pawels 135         
1474 29 Nov 11 pawels 136       }
1474 29 Nov 11 pawels 137       
1474 29 Nov 11 pawels 138       // check & fix protocols
1474 29 Nov 11 pawels 139       checkProtocolColumns(entry, type);
1474 29 Nov 11 pawels 140   
1474 29 Nov 11 pawels 141       
1474 29 Nov 11 pawels 142       // update if the code above added anything to the entries
1474 29 Nov 11 pawels 143       newEntryItems = entry.getItems();
1474 29 Nov 11 pawels 144       firstEntryItems = entries.get(0).getItems();    
1474 29 Nov 11 pawels 145       
1474 29 Nov 11 pawels 146       /* 
1474 29 Nov 11 pawels 147        * Check characteristics of the items and insert
1474 29 Nov 11 pawels 148        * placeholders if a characteristic is missing
1474 29 Nov 11 pawels 149        */
1474 29 Nov 11 pawels 150
1474 29 Nov 11 pawels 151       ItemInfo newEntryItem = newEntryItems.get(type);
1474 29 Nov 11 pawels 152       ItemInfo firstEntryItem = firstEntryItems.get(type);
1474 29 Nov 11 pawels 153       List<String> firstEntryNames = firstEntryItem.getAllCharacteristicsNames();
1474 29 Nov 11 pawels 154       List<String> newEntryNames = newEntryItem.getAllCharacteristicsNames();
1474 29 Nov 11 pawels 155       if (MageTabExporterSettings.FILL_MISSING_VALUES) {    // fix this entry or previous entries by adding empty characteristics
1474 29 Nov 11 pawels 156         
1474 29 Nov 11 pawels 157         /* TODO 
1474 29 Nov 11 pawels 158          * SOURCE of a characteristic is optionally written (if not null). If the SDRFCreator
1474 29 Nov 11 pawels 159          * created it for some items and for others not, the code below would fail to fix columns.
1474 29 Nov 11 pawels 160          * Currently no source of characteristic is set (it is always null).
1474 29 Nov 11 pawels 161          */
1474 29 Nov 11 pawels 162         
1474 29 Nov 11 pawels 163         if (!newEntryNames.containsAll(firstEntryNames)) {
1474 29 Nov 11 pawels 164           // if newEntry is missing some of characteristics found in other entries, add them
1474 29 Nov 11 pawels 165           List<String> missingSet = new ArrayList<String>(firstEntryNames);
1474 29 Nov 11 pawels 166           missingSet.removeAll(newEntryNames);
1474 29 Nov 11 pawels 167           
1474 29 Nov 11 pawels 168           for (String missingCharacteristic : missingSet) {
1474 29 Nov 11 pawels 169             newEntryItem.addCharacteristic(missingCharacteristic, null, null);
1474 29 Nov 11 pawels 170           }
1474 29 Nov 11 pawels 171         } 
1474 29 Nov 11 pawels 172           
1474 29 Nov 11 pawels 173         if (!firstEntryNames.containsAll(newEntryNames)) {
1474 29 Nov 11 pawels 174           // if other entries are missing some of characteristics found in newEntry, add them
1474 29 Nov 11 pawels 175           List<String> missingSet = new ArrayList<String>(newEntryNames);
1474 29 Nov 11 pawels 176           missingSet.removeAll(firstEntryNames);
1474 29 Nov 11 pawels 177
1474 29 Nov 11 pawels 178           for (String missingCharacteristic : missingSet) {
1474 29 Nov 11 pawels 179             for (SDRFEntry e : entries) {
1474 29 Nov 11 pawels 180               e.getItems().get(type).addCharacteristic(missingCharacteristic,null,null);
1474 29 Nov 11 pawels 181             }
1474 29 Nov 11 pawels 182           }
1474 29 Nov 11 pawels 183         }
1474 29 Nov 11 pawels 184         
1474 29 Nov 11 pawels 185       } else {
1474 29 Nov 11 pawels 186         if (!newEntryNames.containsAll(firstEntryNames)) {
1474 29 Nov 11 pawels 187           throw MageTabException.newMissingItemPropertiesException(newEntryItem);
1474 29 Nov 11 pawels 188         } else if (!firstEntryNames.containsAll(newEntryNames)) {
1474 29 Nov 11 pawels 189           throw MageTabException.newMissingItemPropertiesException(firstEntryItem);
1474 29 Nov 11 pawels 190         }  
1474 29 Nov 11 pawels 191       }
1474 29 Nov 11 pawels 192     }
1474 29 Nov 11 pawels 193   }
1474 29 Nov 11 pawels 194
1474 29 Nov 11 pawels 195
1474 29 Nov 11 pawels 196   private void checkProtocolColumns(SDRFEntry newEntry, ItemInfo.TYPE type) throws MageTabException {
1474 29 Nov 11 pawels 197     Hashtable<ItemInfo.TYPE, ItemInfo> newEntryItems = newEntry.getItems();
1474 29 Nov 11 pawels 198     Hashtable<ItemInfo.TYPE, ItemInfo> firstEntryItems = entries.get(0).getItems();
1474 29 Nov 11 pawels 199     
1474 29 Nov 11 pawels 200     /*
1474 29 Nov 11 pawels 201      * Check protocol and try to fix it (if it is sampling or extraction) 
1474 29 Nov 11 pawels 202      * inserting a placeholder if the protocol is missing
1474 29 Nov 11 pawels 203      */
1474 29 Nov 11 pawels 204
1474 29 Nov 11 pawels 205     ItemInfo newEntryItem = newEntryItems.get(type);
1474 29 Nov 11 pawels 206     ItemInfo firstEntryItem = firstEntryItems.get(type);
1474 29 Nov 11 pawels 207
1474 29 Nov 11 pawels 208     // fix sampling and extraction protocols
1474 29 Nov 11 pawels 209     if (MageTabExporterSettings.FILL_MISSING_VALUES &&
1474 29 Nov 11 pawels 210        (type.equals(ItemInfo.TYPE.SAMPLE) || type.equals(ItemInfo.TYPE.EXTRACT))) {
1474 29 Nov 11 pawels 211
1474 29 Nov 11 pawels 212       /*
1474 29 Nov 11 pawels 213        * Fix this entry or previous entries by adding empty protocol.
1474 29 Nov 11 pawels 214        * Possible only for sampling and extraction protocols, and only if
1474 29 Nov 11 pawels 215        * corresponding biosource or/and sample are not present.
1474 29 Nov 11 pawels 216        */
1474 29 Nov 11 pawels 217
1474 29 Nov 11 pawels 218       // get the type of the protocol to set on the item with type that is
1474 29 Nov 11 pawels 219       // revised in this iteration two types are considered since only 
1474 29 Nov 11 pawels 220       // samples and extracts are revised here
1474 29 Nov 11 pawels 221       ProtocolInfo.TYPE pType = type.equals(ItemInfo.TYPE.SAMPLE) ? 
1474 29 Nov 11 pawels 222           ProtocolInfo.TYPE.SAMPLING : ProtocolInfo.TYPE.EXTRACTION;
1474 29 Nov 11 pawels 223
1474 29 Nov 11 pawels 224       // the new one is missing a protocol the previous ones have
1474 29 Nov 11 pawels 225       if (newEntryItem.getProtocol() == null && firstEntryItem.getProtocol() != null) {
1474 29 Nov 11 pawels 226
1474 29 Nov 11 pawels 227         // if the missing protocol has a non-empty item it was used on,
1474 29 Nov 11 pawels 228         // throw an exception
1474 29 Nov 11 pawels 229         if ((type.equals(ItemInfo.TYPE.SAMPLE) && 
1474 29 Nov 11 pawels 230           newEntryItems.containsKey(ItemInfo.TYPE.SOURCE) &&
1474 29 Nov 11 pawels 231           newEntryItems.get(ItemInfo.TYPE.SOURCE).getName() != null)
1474 29 Nov 11 pawels 232             || 
1474 29 Nov 11 pawels 233           (type.equals(ItemInfo.TYPE.EXTRACT)  && 
1474 29 Nov 11 pawels 234           newEntryItems.containsKey(ItemInfo.TYPE.SAMPLE) &&
1474 29 Nov 11 pawels 235           newEntryItems.get(ItemInfo.TYPE.SAMPLE).getName() != null)) {
1474 29 Nov 11 pawels 236
1474 29 Nov 11 pawels 237           throw MageTabException.newMissingProtocolException(newEntryItem);
1474 29 Nov 11 pawels 238
1474 29 Nov 11 pawels 239         } else {
1474 29 Nov 11 pawels 240           newEntryItem.setProtocol(new ProtocolInfo(pType, null, null));
1474 29 Nov 11 pawels 241         }
1474 29 Nov 11 pawels 242
1474 29 Nov 11 pawels 243       } else if (newEntryItem.getProtocol() != null && firstEntryItem.getProtocol() == null) {
1474 29 Nov 11 pawels 244         // the new one has a protocol that the previous ones miss
1474 29 Nov 11 pawels 245
1474 29 Nov 11 pawels 246         for (SDRFEntry e : entries) {
1474 29 Nov 11 pawels 247           ProtocolInfo pi = new ProtocolInfo(pType, null, null);
1474 29 Nov 11 pawels 248           ItemInfo item = e.getItems().get(type);
1474 29 Nov 11 pawels 249           item.setProtocol(pi);
1474 29 Nov 11 pawels 250         }
1474 29 Nov 11 pawels 251
1474 29 Nov 11 pawels 252       } else if (newEntryItem.getProtocol() == null && firstEntryItem.getProtocol() == null) {
1474 29 Nov 11 pawels 253         // neither has a protocol of this type - move to the next type
1474 29 Nov 11 pawels 254         return;
1474 29 Nov 11 pawels 255       } else {
1474 29 Nov 11 pawels 256         // both have a protocol of this type - check for missing
1474 29 Nov 11 pawels 257         // protocol parameters
1474 29 Nov 11 pawels 258       }
1474 29 Nov 11 pawels 259
1474 29 Nov 11 pawels 260     } else { // throw an exception or ignore if none of the entries has the
1474 29 Nov 11 pawels 261           // item
1474 29 Nov 11 pawels 262
1474 29 Nov 11 pawels 263       if (newEntryItem.getProtocol() == null && firstEntryItem.getProtocol() != null) {
1474 29 Nov 11 pawels 264         // existing entries have the protocol and the new one has not
1474 29 Nov 11 pawels 265         throw MageTabException.newMissingProtocolException(newEntryItem);
1474 29 Nov 11 pawels 266       } else if (newEntryItem.getProtocol() != null && firstEntryItem.getProtocol() == null) {
1474 29 Nov 11 pawels 267         // existing entries dont have the protocol and the new one has
1474 29 Nov 11 pawels 268         throw MageTabException.newMissingProtocolException(firstEntryItem);
1474 29 Nov 11 pawels 269       } else if (newEntryItem.getProtocol() == null && firstEntryItem.getProtocol() == null) {
1474 29 Nov 11 pawels 270         // neither has a protocol of this type - move to the next type
1474 29 Nov 11 pawels 271         return;
1474 29 Nov 11 pawels 272       } else {
1474 29 Nov 11 pawels 273         // both have a protocol of this type - check for missing
1474 29 Nov 11 pawels 274         // protocol parameters
1474 29 Nov 11 pawels 275       }
1474 29 Nov 11 pawels 276     }
1474 29 Nov 11 pawels 277
1474 29 Nov 11 pawels 278     /*
1474 29 Nov 11 pawels 279      * Check parameters of the protocols and insert placeholders if a
1474 29 Nov 11 pawels 280      * parameter is missing
1474 29 Nov 11 pawels 281      */
1474 29 Nov 11 pawels 282
1474 29 Nov 11 pawels 283     ProtocolInfo newEntryProtocol = newEntryItem.getProtocol();
1474 29 Nov 11 pawels 284     ProtocolInfo firstEntryProtocol = firstEntryItem.getProtocol();
1474 29 Nov 11 pawels 285     List<String> firstEntryNames = firstEntryProtocol.getAllParameterNames();
1474 29 Nov 11 pawels 286     List<String> newEntryNames = newEntryProtocol.getAllParameterNames();
1474 29 Nov 11 pawels 287     if (MageTabExporterSettings.FILL_MISSING_VALUES) {
1474 29 Nov 11 pawels 288
1474 29 Nov 11 pawels 289       if (!newEntryNames.containsAll(firstEntryNames)) {
1474 29 Nov 11 pawels 290         // if newEntry is missing some of protocol parameters found in
1474 29 Nov 11 pawels 291         // other entries, add them
1474 29 Nov 11 pawels 292         List<String> missingSet = new ArrayList<String>(firstEntryNames);
1474 29 Nov 11 pawels 293         missingSet.removeAll(newEntryNames);
1474 29 Nov 11 pawels 294
1474 29 Nov 11 pawels 295         for (String missingParam : missingSet) {
1474 29 Nov 11 pawels 296           newEntryProtocol.addParameter(missingParam, null);
1474 29 Nov 11 pawels 297         }
1474 29 Nov 11 pawels 298       }
1474 29 Nov 11 pawels 299
1474 29 Nov 11 pawels 300       if (!firstEntryNames.containsAll(newEntryNames)) {
1474 29 Nov 11 pawels 301         // if other entries are missing some of protocol parameters
1474 29 Nov 11 pawels 302         // found in newEntry, add them
1474 29 Nov 11 pawels 303         List<String> missingSet = new ArrayList<String>(newEntryNames);
1474 29 Nov 11 pawels 304         missingSet.removeAll(firstEntryNames);
1474 29 Nov 11 pawels 305
1474 29 Nov 11 pawels 306         for (String missingParam : missingSet) {
1474 29 Nov 11 pawels 307           for (SDRFEntry e : entries) {
1474 29 Nov 11 pawels 308             e.getItems().get(type).getProtocol().addParameter(missingParam, null);
1474 29 Nov 11 pawels 309           }
1474 29 Nov 11 pawels 310         }
1474 29 Nov 11 pawels 311       }
1474 29 Nov 11 pawels 312
1474 29 Nov 11 pawels 313     } else {
1474 29 Nov 11 pawels 314
1474 29 Nov 11 pawels 315       /*
1474 29 Nov 11 pawels 316        * TODO This may throw unnecessary and/or misleading exceptions if
1474 29 Nov 11 pawels 317        * different protocols (having different sets of parameters) of the
1474 29 Nov 11 pawels 318        * same type would be set in different entries. Should the
1474 29 Nov 11 pawels 319        * !FILL_WITH_EMPTY scenario be dropped?
1474 29 Nov 11 pawels 320        */
1474 29 Nov 11 pawels 321
1474 29 Nov 11 pawels 322       if (!newEntryNames.containsAll(firstEntryNames)) {
1474 29 Nov 11 pawels 323         throw MageTabException.newMissingProtocolPropertiesException(newEntryProtocol);
1474 29 Nov 11 pawels 324       } else if (!firstEntryNames.containsAll(newEntryNames)) {
1474 29 Nov 11 pawels 325         throw MageTabException.newMissingProtocolPropertiesException(firstEntryProtocol);
1474 29 Nov 11 pawels 326       }
1474 29 Nov 11 pawels 327     }
1474 29 Nov 11 pawels 328     
1474 29 Nov 11 pawels 329   }
1474 29 Nov 11 pawels 330   
1474 29 Nov 11 pawels 331   public List<ProtocolInfo> getReferencedProtocols() {
1474 29 Nov 11 pawels 332     HashSet<ProtocolInfo> protocols = new HashSet<ProtocolInfo>();
1474 29 Nov 11 pawels 333     for (SDRFEntry e : entries) {
1474 29 Nov 11 pawels 334       for (ItemInfo item : e.getItems().values()) {
1474 29 Nov 11 pawels 335         if (item != null && item.getProtocol() != null) {
1474 29 Nov 11 pawels 336           protocols.add(item.getProtocol());  
1474 29 Nov 11 pawels 337         }
1474 29 Nov 11 pawels 338       }
1474 29 Nov 11 pawels 339     }
1474 29 Nov 11 pawels 340     return new ArrayList<ProtocolInfo>(protocols);
1474 29 Nov 11 pawels 341   }
1474 29 Nov 11 pawels 342
1474 29 Nov 11 pawels 343   public List<String> getExperimentFactors() {
1474 29 Nov 11 pawels 344     List<String> factors = new ArrayList<String>();
1474 29 Nov 11 pawels 345     if (!entries.isEmpty()) {
1474 29 Nov 11 pawels 346       factors.addAll(entries.get(0).getFactors().keySet());
1474 29 Nov 11 pawels 347     }
1474 29 Nov 11 pawels 348     return factors;
1474 29 Nov 11 pawels 349   }
1474 29 Nov 11 pawels 350
1474 29 Nov 11 pawels 351
1474 29 Nov 11 pawels 352   public String getHeader() {
1474 29 Nov 11 pawels 353     if (header == null) {
1474 29 Nov 11 pawels 354       makeHeader();
1474 29 Nov 11 pawels 355     }
1474 29 Nov 11 pawels 356     return header;
1474 29 Nov 11 pawels 357   }
1474 29 Nov 11 pawels 358
1474 29 Nov 11 pawels 359   
1474 29 Nov 11 pawels 360   private void makeHeader() {
1474 29 Nov 11 pawels 361     StringBuilder sb = new StringBuilder();
1474 29 Nov 11 pawels 362     
1474 29 Nov 11 pawels 363     // all entries should have the same number and order of columns so 
1474 29 Nov 11 pawels 364     // any could be chosen here
1474 29 Nov 11 pawels 365     Hashtable<ItemInfo.TYPE, ItemInfo> items = entries.get(0).getItems();
1474 29 Nov 11 pawels 366     
1474 29 Nov 11 pawels 367     ItemInfo item = items.get(ItemInfo.TYPE.SOURCE);
1474 29 Nov 11 pawels 368     sb.append(getItemHeader(item, SOURCE_NAME, false));
1474 29 Nov 11 pawels 369     
1474 29 Nov 11 pawels 370     item = items.get(ItemInfo.TYPE.SAMPLE);
1474 29 Nov 11 pawels 371     sb.append(getItemHeader(item, SAMPLE_NAME, true));
1474 29 Nov 11 pawels 372     
1474 29 Nov 11 pawels 373     item = items.get(ItemInfo.TYPE.POOLED_SAMPLE);
1474 29 Nov 11 pawels 374     sb.append(getItemHeader(item, SAMPLE_NAME, true));
1474 29 Nov 11 pawels 375
1474 29 Nov 11 pawels 376     item = items.get(ItemInfo.TYPE.EXTRACT);
1474 29 Nov 11 pawels 377     sb.append(getItemHeader(item, EXTRACT_NAME, true));
1474 29 Nov 11 pawels 378
1474 29 Nov 11 pawels 379     item = items.get(ItemInfo.TYPE.POOLED_EXTRACT);
1474 29 Nov 11 pawels 380     sb.append(getItemHeader(item, EXTRACT_NAME, true));
1474 29 Nov 11 pawels 381
1474 29 Nov 11 pawels 382     item = items.get(ItemInfo.TYPE.LABELED_EXTRACT);
1474 29 Nov 11 pawels 383     sb.append(getItemHeader(item, LABELED_EXTRACT_NAME, true));
1474 29 Nov 11 pawels 384
1474 29 Nov 11 pawels 385     item = items.get(ItemInfo.TYPE.POOLED_LABELED_EXTRACT);
1474 29 Nov 11 pawels 386     sb.append(getItemHeader(item, LABELED_EXTRACT_NAME, true));
1474 29 Nov 11 pawels 387
1474 29 Nov 11 pawels 388     item = items.get(ItemInfo.TYPE.HYBRIDIZATION);
1474 29 Nov 11 pawels 389     sb.append(getItemHeader(item, HYBRIDIZATION_NAME, true));
1474 29 Nov 11 pawels 390
1474 29 Nov 11 pawels 391     item = items.get(ItemInfo.TYPE.SCAN);
1474 29 Nov 11 pawels 392     sb.append(getItemHeader(item, SCAN_NAME, true));
1474 29 Nov 11 pawels 393
1474 29 Nov 11 pawels 394     item = items.get(ItemInfo.TYPE.ARRAY_DATA_FILE);
1474 29 Nov 11 pawels 395     sb.append(getItemHeader(item, ARRAY_DATA_FILE, false));
1474 29 Nov 11 pawels 396     
1474 29 Nov 11 pawels 397     item = items.get(ItemInfo.TYPE.NORMALIZATION);
1474 29 Nov 11 pawels 398     sb.append(getItemHeader(item, NORMALIZATION_NAME, true));
1474 29 Nov 11 pawels 399     
1474 29 Nov 11 pawels 400     item = items.get(ItemInfo.TYPE.DERIVED_ARRAY_DATA_FILE);
1474 29 Nov 11 pawels 401     sb.append(getItemHeader(item, DERIVED_ARRAY_DATA_MATRIX_FILE, true));
1474 29 Nov 11 pawels 402
1474 29 Nov 11 pawels 403     sb.append(getFactorsHeader());
1474 29 Nov 11 pawels 404     
1474 29 Nov 11 pawels 405     // remove the trailing delimiter 
1474 29 Nov 11 pawels 406     header = sb.toString();
1474 29 Nov 11 pawels 407     if (header.endsWith(DELIMITER)) {
1474 29 Nov 11 pawels 408       header = header.substring(0, header.length() - DELIMITER.length());
1474 29 Nov 11 pawels 409     }
1474 29 Nov 11 pawels 410   }
1474 29 Nov 11 pawels 411   
1474 29 Nov 11 pawels 412   private String getItemHeader(ItemInfo itemInfo, String itemColumnName, boolean withProtocol) {
1474 29 Nov 11 pawels 413     
1474 29 Nov 11 pawels 414     if (itemInfo == null) { return ""; }
1474 29 Nov 11 pawels 415     
1474 29 Nov 11 pawels 416     String output = withProtocol ? getProtocolHeader(itemInfo.getProtocol()) : "";
1474 29 Nov 11 pawels 417     
1474 29 Nov 11 pawels 418     output += Utils.quote(itemColumnName) + DELIMITER;
1474 29 Nov 11 pawels 419     
1474 29 Nov 11 pawels 420     // include type specific columns
1474 29 Nov 11 pawels 421     if (itemInfo.getType().equals(ItemInfo.TYPE.LABELED_EXTRACT)) {
1474 29 Nov 11 pawels 422       output += Utils.quote(LABEL) + DELIMITER;
1474 29 Nov 11 pawels 423     } 
1474 29 Nov 11 pawels 424     if (itemInfo.isBioMaterial()) {
1474 29 Nov 11 pawels 425       output += Utils.quote(MATERIAL_TYPE) + DELIMITER;
1474 29 Nov 11 pawels 426     }
1474 29 Nov 11 pawels 427     if (itemInfo.getType().equals(ItemInfo.TYPE.HYBRIDIZATION)) {
1474 29 Nov 11 pawels 428       output += Utils.quote(ARRAY_DESIGN_REF) + DELIMITER;
1474 29 Nov 11 pawels 429       output += Utils.quote(TERM_SOURCE_REF) + DELIMITER;
1474 29 Nov 11 pawels 430     }  
1474 29 Nov 11 pawels 431     
1474 29 Nov 11 pawels 432     for (String name : itemInfo.getAllCharacteristicsNames()) {
1474 29 Nov 11 pawels 433       output += Utils.quote(CHARACTERISTICS + " [" + name + "]") + DELIMITER;
1474 29 Nov 11 pawels 434       if (itemInfo.getCharacteristicSource(name) != null) {
1474 29 Nov 11 pawels 435         output += Utils.quote(TERM_SOURCE_REF) + DELIMITER;
1474 29 Nov 11 pawels 436       }
1474 29 Nov 11 pawels 437     }
1474 29 Nov 11 pawels 438     return output;
1474 29 Nov 11 pawels 439   }
1474 29 Nov 11 pawels 440   
1474 29 Nov 11 pawels 441
1474 29 Nov 11 pawels 442   private String getProtocolHeader(ProtocolInfo protocolInfo) {
1474 29 Nov 11 pawels 443     String output = Utils.quote(PROTOCOL_REF) + DELIMITER + 
1474 29 Nov 11 pawels 444             Utils.quote(TERM_SOURCE_REF) + DELIMITER;
1474 29 Nov 11 pawels 445     if (protocolInfo != null) {
1474 29 Nov 11 pawels 446       for (String name : protocolInfo.getAllParameterNames()) {
1474 29 Nov 11 pawels 447         output += Utils.quote(PARAMETER_VALUE + " [" + name + "]") + DELIMITER;
1474 29 Nov 11 pawels 448       }
1474 29 Nov 11 pawels 449     }
1474 29 Nov 11 pawels 450     return output;
1474 29 Nov 11 pawels 451   }
1474 29 Nov 11 pawels 452
1474 29 Nov 11 pawels 453   
1474 29 Nov 11 pawels 454   private String getFactorsHeader() {
1474 29 Nov 11 pawels 455     String output = "";
1474 29 Nov 11 pawels 456     for (String name : getExperimentFactors()) {
1474 29 Nov 11 pawels 457       output += Utils.quote(FACTOR_VALUE + " [" + name + "]") + DELIMITER;
1474 29 Nov 11 pawels 458     }
1474 29 Nov 11 pawels 459     return output;
1474 29 Nov 11 pawels 460   }
1474 29 Nov 11 pawels 461
1474 29 Nov 11 pawels 462 }