edu.stanford.epad.epadws.service.TCIAService.java Source code

Java tutorial

Introduction

Here is the source code for edu.stanford.epad.epadws.service.TCIAService.java

Source

/*******************************************************************************
 * Copyright (c) 2015 The Board of Trustees of the Leland Stanford Junior University
 * BY CLICKING ON "ACCEPT," DOWNLOADING, OR OTHERWISE USING EPAD, YOU AGREE TO THE FOLLOWING TERMS AND CONDITIONS:
 * STANFORD ACADEMIC SOFTWARE SOURCE CODE LICENSE FOR
 * "ePAD Annotation Platform for Radiology Images"
 *
 * This Agreement covers contributions to and downloads from the ePAD project ("ePAD") maintained by The Board of Trustees 
 * of the Leland Stanford Junior University ("Stanford"). 
 *
 * *   Part A applies to downloads of ePAD source code and/or data from ePAD. 
 *
 * *   Part B applies to contributions of software and/or data to ePAD (including making revisions of or additions to code 
 * and/or data already in ePAD), which may include source or object code. 
 *
 * Your download, copying, modifying, displaying, distributing or use of any ePAD software and/or data from ePAD 
 * (collectively, the "Software") is subject to Part A. Your contribution of software and/or data to ePAD (including any 
 * that occurred prior to the first publication of this Agreement) is a "Contribution" subject to Part B. Both Parts A and 
 * B shall be governed by and construed in accordance with the laws of the State of California without regard to principles 
 * of conflicts of law. Any legal action involving this Agreement or the Research Program will be adjudicated in the State 
 * of California. This Agreement shall supersede and replace any license terms that you may have agreed to previously with 
 * respect to ePAD.
 *
 * PART A. DOWNLOADING AGREEMENT - LICENSE FROM STANFORD WITH RIGHT TO SUBLICENSE ("SOFTWARE LICENSE").
 * 1. As used in this Software License, "you" means the individual downloading and/or using, reproducing, modifying, 
 * displaying and/or distributing Software and the institution or entity which employs or is otherwise affiliated with you. 
 * Stanford  hereby grants you, with right to sublicense, with respect to Stanford's rights in the Software, a 
 * royalty-free, non-exclusive license to use, reproduce, make derivative works of, display and distribute the Software, 
 * provided that: (a) you adhere to all of the terms and conditions of this Software License; (b) in connection with any 
 * copy, distribution of, or sublicense of all or any portion of the Software, the terms and conditions in this Software 
 * License shall appear in and shall apply to such copy and such sublicense, including without limitation all source and 
 * executable forms and on any user documentation, prefaced with the following words: "All or portions of this licensed 
 * product  have been obtained under license from The Board of Trustees of the Leland Stanford Junior University. and are 
 * subject to the following terms and conditions" AND any user interface to the Software or the "About" information display 
 * in the Software will display the following: "Powered by ePAD http://epad.stanford.edu;" (c) you preserve and maintain 
 * all applicable attributions, copyright notices and licenses included in or applicable to the Software; (d) modified 
 * versions of the Software must be clearly identified and marked as such, and must not be misrepresented as being the 
 * original Software; and (e) you consider making, but are under no obligation to make, the source code of any of your 
 * modifications to the Software freely available to others on an open source basis.
 *
 * 2. The license granted in this Software License includes without limitation the right to (i) incorporate the Software 
 * into your proprietary programs (subject to any restrictions applicable to such programs), (ii) add your own copyright 
 * statement to your modifications of the Software, and (iii) provide additional or different license terms and conditions 
 * in your sublicenses of modifications of the Software; provided that in each case your use, reproduction or distribution 
 * of such modifications otherwise complies with the conditions stated in this Software License.
 * 3. This Software License does not grant any rights with respect to third party software, except those rights that 
 * Stanford has been authorized by a third party to grant to you, and accordingly you are solely responsible for (i) 
 * obtaining any permissions from third parties that you need to use, reproduce, make derivative works of, display and 
 * distribute the Software, and (ii) informing your sublicensees, including without limitation your end-users, of their 
 * obligations to secure any such required permissions.
 * 4. You agree that you will use the Software in compliance with all applicable laws, policies and regulations including, 
 * but not limited to, those applicable to Personal Health Information ("PHI") and subject to the Institutional Review 
 * Board requirements of the your institution, if applicable. Licensee acknowledges and agrees that the Software is not 
 * FDA-approved, is intended only for research, and may not be used for clinical treatment purposes. Any commercialization 
 * of the Software is at the sole risk of you and the party or parties engaged in such commercialization. You further agree 
 * to use, reproduce, make derivative works of, display and distribute the Software in compliance with all applicable 
 * governmental laws, regulations and orders, including without limitation those relating to export and import control.
 * 5. You or your institution, as applicable, will indemnify, hold harmless, and defend Stanford against any third party 
 * claim of any kind made against Stanford arising out of or related to the exercise of any rights granted under this 
 * Agreement, the provision of Software, or the breach of this Agreement. Stanford provides the Software AS IS and WITH ALL 
 * FAULTS.  Stanford makes no representations and extends no warranties of any kind, either express or implied.  Among 
 * other things, Stanford disclaims any express or implied warranty in the Software:
 * (a)  of merchantability, of fitness for a particular purpose,
 * (b)  of non-infringement or 
 * (c)  arising out of any course of dealing.
 *
 * Title and copyright to the Program and any associated documentation shall at all times remain with Stanford, and 
 * Licensee agrees to preserve same. Stanford reserves the right to license the Program at any time for a fee.
 * 6. None of the names, logos or trademarks of Stanford or any of Stanford's affiliates or any of the Contributors, or any 
 * funding agency, may be used to endorse or promote products produced in whole or in part by operation of the Software or 
 * derived from or based on the Software without specific prior written permission from the applicable party.
 * 7. Any use, reproduction or distribution of the Software which is not in accordance with this Software License shall 
 * automatically revoke all rights granted to you under this Software License and render Paragraphs 1 and 2 of this 
 * Software License null and void.
 * 8. This Software License does not grant any rights in or to any intellectual property owned by Stanford or any 
 * Contributor except those rights expressly granted hereunder.
 *
 * PART B. CONTRIBUTION AGREEMENT - LICENSE TO STANFORD WITH RIGHT TO SUBLICENSE ("CONTRIBUTION AGREEMENT").
 * 1. As used in this Contribution Agreement, "you" means an individual providing a Contribution to ePAD and the 
 * institution or entity which employs or is otherwise affiliated with you.
 * 2. This Contribution Agreement applies to all Contributions made to ePAD at any time. By making a Contribution you 
 * represent that: (i) you are legally authorized and entitled by ownership or license to make such Contribution and to 
 * grant all licenses granted in this Contribution Agreement with respect to such Contribution; (ii) if your Contribution 
 * includes any patient data, all such data is de-identified in accordance with U.S. confidentiality and security laws and 
 * requirements, including but not limited to the Health Insurance Portability and Accountability Act (HIPAA) and its 
 * regulations, and your disclosure of such data for the purposes contemplated by this Agreement is properly authorized and 
 * in compliance with all applicable laws and regulations; and (iii) you have preserved in the Contribution all applicable 
 * attributions, copyright notices and licenses for any third party software or data included in the Contribution.
 * 3. Except for the licenses you grant in this Agreement, you reserve all right, title and interest in your Contribution.
 * 4. You hereby grant to Stanford, with the right to sublicense, a perpetual, worldwide, non-exclusive, no charge, 
 * royalty-free, irrevocable license to use, reproduce, make derivative works of, display and distribute the Contribution. 
 * If your Contribution is protected by patent, you hereby grant to Stanford, with the right to sublicense, a perpetual, 
 * worldwide, non-exclusive, no-charge, royalty-free, irrevocable license under your interest in patent rights embodied in 
 * the Contribution, to make, have made, use, sell and otherwise transfer your Contribution, alone or in combination with 
 * ePAD or otherwise.
 * 5. You acknowledge and agree that Stanford ham may incorporate your Contribution into ePAD and may make your 
 * Contribution as incorporated available to members of the public on an open source basis under terms substantially in 
 * accordance with the Software License set forth in Part A of this Agreement. You further acknowledge and agree that 
 * Stanford shall have no liability arising in connection with claims resulting from your breach of any of the terms of 
 * this Agreement.
 * 6. YOU WARRANT THAT TO THE BEST OF YOUR KNOWLEDGE YOUR CONTRIBUTION DOES NOT CONTAIN ANY CODE OBTAINED BY YOU UNDER AN 
 * OPEN SOURCE LICENSE THAT REQUIRES OR PRESCRIBES DISTRBUTION OF DERIVATIVE WORKS UNDER SUCH OPEN SOURCE LICENSE. (By way 
 * of non-limiting example, you will not contribute any code obtained by you under the GNU General Public License or other 
 * so-called "reciprocal" license.)
 *******************************************************************************/
package edu.stanford.epad.epadws.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.IOUtils;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import edu.stanford.epad.common.util.EPADConfig;
import edu.stanford.epad.common.util.EPADLogger;
import edu.stanford.epad.common.util.Encryption;
import edu.stanford.epad.dtos.RemotePACEntity;
import edu.stanford.epad.dtos.TaskStatus;

/**
 * Class to query TCIA data. See https://wiki.cancerimagingarchive.net/display/Public/Wiki
 * 
 * @author Dev Gude
 *
 */
public class TCIAService {

    static final EPADLogger log = EPADLogger.getInstance();

    static TCIAService tciainstance;

    public static final String TCIA_URL = "TCIA_URL";
    public static final String TCIA_APIKEY = "TCIA_APIKEY";
    public static final String TCIA_PREFIX = "tcia:";
    public static final String TCIA_SHAREDLISTS = "TCIA_SHAREDLISTS";

    public static String apiKey = null;
    public static List<String> collections = null;
    public static Set<String> sharedLists = new LinkedHashSet<String>();

    public static TCIAService getInstance() throws Exception {
        if (tciainstance == null) {
            tciainstance = new TCIAService();
        }
        return tciainstance;
    }

    private TCIAService() throws Exception {
        String key = EPADConfig.getParamValue(TCIA_APIKEY);
        log.info("key:" + key + " len:" + key.length());
        if (key.length() == 64) {
            Encryption enc = new Encryption(EPADConfig.xnatServer);
            apiKey = enc.decrypt(key);
        } else
            apiKey = key;

        String sharedListsConfig = EPADConfig.getParamValue(TCIA_SHAREDLISTS);
        if (sharedListsConfig != null && sharedListsConfig.trim().length() > 0) {
            String[] lists = sharedListsConfig.split(",");
            for (String list : lists)
                sharedLists.add(list);
        }
    }

    public static long downtime = 0;

    public List<String> getCollections() throws Exception {
        if (collections == null) {
            if (downtime != 0 && ((System.currentTimeMillis() - downtime) < 4 * 3600 * 1000))
                return collections;
            JsonArray collArray = getResponseFromTCIA("getCollectionValues");
            downtime = 0;
            collections = new ArrayList<String>();
            for (int i = 0; i < collArray.size(); i++)
                collections.add(collArray.get(i).getAsJsonObject().get("Collection").getAsString());
            log.info("Collections:" + collections);
            if (collections.size() < 2)
                collections = null;
        }
        return collections;
    }

    public Set<String> getSharedLists() {
        return sharedLists;
    }

    public List<RemotePACEntity> getPatientsForCollection(String collection) throws Exception {
        List<RemotePACEntity> entities = new ArrayList<RemotePACEntity>();
        if (sharedLists.contains(collection)) {
            String entityID = "TCIA" + ":" + collection + ":SUBJECT:UNKNOWN";
            RemotePACEntity entity = new RemotePACEntity("Patient", "UNKNOWN PATIENT", 1, entityID);
            entity.subjectID = "UNKNOWN PATIENT";
            entity.subjectName = "UNKNOWN PATIENT";
            entities.add(entity);
            return entities;
        }

        JsonArray patients = this.getResponseFromTCIA("getPatient?Collection=" + collection);
        for (int i = 0; i < patients.size(); i++) {
            JsonObject patient = patients.get(i).getAsJsonObject();
            String patientID = getJsonString(patient.get("PatientID"));
            String patientName = getJsonString(patient.get("PatientName"));
            if (patientName.length() == 0)
                patientName = patientID;
            //String patientGender = patient.get("PatientSex"));
            //String ethnicity = patient.get("EthnicGroup"));
            String entityID = "TCIA" + ":" + collection + ":SUBJECT:" + patientID;
            RemotePACEntity entity = new RemotePACEntity("Patient", patientName, 1, entityID);
            entity.subjectID = patientID;
            entity.subjectName = patientName;
            entities.add(entity);
        }

        return entities;
    }

    public List<RemotePACEntity> getNewStudiesForPatient(String collection, String patientID, Date sinceDate)
            throws Exception {
        if (sharedLists.contains(collection))
            return new ArrayList<RemotePACEntity>();
        List<RemotePACEntity> entities = new ArrayList<RemotePACEntity>();
        JsonArray studies = this.getResponseFromTCIA("NewStudiesInPatientCollection?Collection=" + collection
                + "&PatientID=" + patientID + "&Date=" + new SimpleDateFormat("yyyy-MM-dd").format(sinceDate));
        for (int i = 0; i < studies.size(); i++) {
            JsonObject study = studies.get(i).getAsJsonObject();
            String patientName = getJsonString(study.get("PatientName"));
            String patientGender = getJsonString(study.get("PatientSex"));
            String ethnicity = getJsonString(study.get("EthnicGroup"));
            String studyUID = getJsonString(study.get("StudyInstanceUID"));
            String description = getJsonString(study.get("StudyDescription"));
            String studyDate = getJsonString(study.get("StudyDate"));
            int seriesCount = study.get("SeriesCount").getAsInt();
            if (description.length() == 0)
                description = studyUID + " " + studyDate;
            String patientAge = getJsonString(study.get("PatientAge"));
            String entityID = "TCIA" + ":" + collection + ":" + patientID + ":STUDY:" + studyUID;
            RemotePACEntity entity = new RemotePACEntity("Study", description, 2, entityID);
            entity.subjectID = patientID;
            entity.subjectName = patientName;
            entities.add(entity);
        }
        return entities;
    }

    public List<RemotePACEntity> getStudiesForPatient(String collection, String patientID) throws Exception {
        List<RemotePACEntity> entities = new ArrayList<RemotePACEntity>();
        if (sharedLists.contains(collection)) {
            String entityID = "TCIA" + ":" + collection + ":SUBJECT:UNKNOWN:STUDY:UNKNOWN";
            RemotePACEntity entity = new RemotePACEntity("Study", "UNKNOWN STUDY", 2, entityID);
            entity.subjectID = "UNKNOWN";
            entity.subjectName = "UNKNOWN";
            entity.studyDate = "";
            entity.studyDescription = "";
            entities.add(entity);
            return entities;
        }

        JsonArray studies = this
                .getResponseFromTCIA("getPatientStudy?Collection=" + collection + "&PatientID=" + patientID);
        for (int i = 0; i < studies.size(); i++) {
            JsonObject study = studies.get(i).getAsJsonObject();
            String patientName = getJsonString(study.get("PatientName"));
            String patientGender = getJsonString(study.get("PatientSex"));
            String ethnicity = getJsonString(study.get("EthnicGroup"));
            String studyUID = getJsonString(study.get("StudyInstanceUID"));
            String description = getJsonString(study.get("StudyDescription"));
            String studyDate = getJsonString(study.get("StudyDate"));
            int seriesCount = study.get("SeriesCount").getAsInt();
            if (description.length() == 0)
                description = studyUID + " " + studyDate;
            String patientAge = getJsonString(study.get("PatientAge"));
            String entityID = "TCIA" + ":" + collection + ":" + patientID + ":STUDY:" + studyUID;
            RemotePACEntity entity = new RemotePACEntity("Study", description, 2, entityID);
            entity.subjectID = patientID;
            entity.subjectName = patientName;
            entity.studyDate = studyDate;
            entity.studyDescription = description;
            entities.add(entity);
        }
        return entities;
    }

    public List<RemotePACEntity> getSeriesForStudy(String collection, String patientID, String studyUID)
            throws Exception {
        if (sharedLists.contains(collection))
            return getSeriesForSharedLists(collection);
        List<RemotePACEntity> entities = new ArrayList<RemotePACEntity>();
        JsonArray seriess = this.getResponseFromTCIA(
                "getSeries?Collection=" + collection + "&PatientID=" + patientID + "&StudyInstanceUID=" + studyUID);
        for (int i = 0; i < seriess.size(); i++) {
            JsonObject series = seriess.get(i).getAsJsonObject();
            String seriesUID = getJsonString(series.get("SeriesInstanceUID"));
            String modality = getJsonString(series.get("Modality"));
            String seriesDate = getJsonString(series.get("SeriesDate"));
            String description = getJsonString(series.get("SeriesDescription"));
            String bodyPart = getJsonString(series.get("BodyPartExamined"));
            String seriesNumber = getJsonString(series.get("SeriesNumber"));
            String protocol = getJsonString(series.get("ProtocolName"));
            String manufacturer = getJsonString(series.get("Manufacturer"));
            String model = getJsonString(series.get("ManufacturerModelName"));
            String softwareVersion = getJsonString(series.get("SoftwareVersions"));
            int imageCount = series.get("ImageCount").getAsInt();
            if (description.length() == 0)
                description = bodyPart + " " + modality + " " + seriesDate;

            String entityID = "TCIA" + ":" + collection + ":" + patientID + ":" + studyUID + ":SERIES:" + seriesUID;
            RemotePACEntity entity = new RemotePACEntity("Series", description, 3, entityID);
            entities.add(entity);
        }
        return entities;
    }

    public List<RemotePACEntity> getSeriesForSharedLists(String collection) throws Exception {
        String query = "ContentsByName?name=" + collection;
        List<RemotePACEntity> entities = new ArrayList<RemotePACEntity>();
        JsonArray seriess = this.getResponseFromTCIA(query, true);
        for (int i = 0; i < seriess.size(); i++) {
            JsonObject series = seriess.get(i).getAsJsonObject();
            String seriesUID = getJsonString(series.get("SERIES_INSTANCE_UID"));

            String entityID = "TCIA" + ":" + collection + ":::SERIES:" + seriesUID;
            RemotePACEntity entity = new RemotePACEntity("Series", seriesUID, 3, entityID);
            entities.add(entity);
            entity.subjectID = seriesUID;
            entity.subjectName = seriesUID;
        }
        return entities;
    }

    private String getJsonString(JsonElement elem) {
        if (elem == null)
            return "";
        else
            return elem.getAsString();
    }

    public int downloadPatientFromTCIA(String username, String collection, String patientID, String projectID)
            throws Exception {
        if (sharedLists.contains(collection))
            return downloadSeriesFromTCIA(username, patientID, projectID); // Shared Lists only have SeriesUID
        EpadProjectOperations projectOperations = DefaultEpadProjectOperations.getInstance();
        projectOperations.updateUserTaskStatus(username, TaskStatus.TASK_TCIA_DOWNLOAD, patientID,
                "Started download", new Date(), null);
        List<RemotePACEntity> entities = getStudiesForPatient(collection, patientID);
        for (RemotePACEntity entity : entities) {
            String studyUID = entity.entityID;
            if (studyUID.indexOf(":") != -1)
                studyUID = studyUID.substring(studyUID.lastIndexOf(":") + 1);
            downloadStudyFromTCIA(username, collection, patientID, studyUID, projectID);
        }
        projectOperations.updateUserTaskStatus(username, TaskStatus.TASK_TCIA_DOWNLOAD, patientID,
                "Completed download", null, new Date());
        return HttpServletResponse.SC_OK;
    }

    public int downloadStudyFromTCIA(String username, String collection, String patientID, String studyUID,
            String projectID) throws Exception {
        if (sharedLists.contains(collection))
            return downloadSeriesFromTCIA(username, patientID, projectID);
        EpadProjectOperations projectOperations = DefaultEpadProjectOperations.getInstance();
        projectOperations.updateUserTaskStatus(username, TaskStatus.TASK_TCIA_DOWNLOAD,
                "Patient:" + patientID + ", Study:" + studyUID, "Started download", null, null);
        List<RemotePACEntity> entities = getSeriesForStudy(collection, patientID, studyUID);
        for (RemotePACEntity entity : entities) {
            String seriesUID = entity.entityID;
            if (seriesUID.indexOf(":") != -1)
                seriesUID = seriesUID.substring(seriesUID.lastIndexOf(":") + 1);
            downloadSeriesFromTCIA(username, seriesUID, projectID);
        }
        projectOperations.updateUserTaskStatus(username, TaskStatus.TASK_TCIA_DOWNLOAD,
                "Patient:" + patientID + ", Study:" + studyUID, "Completed download", null, new Date());
        return HttpServletResponse.SC_OK;
    }

    public static int downloadSeriesFromTCIA(String username, String seriesUID, String projectID) throws Exception {
        String tciaURL = EPADConfig.getParamValue(TCIA_URL,
                "https://services.cancerimagingarchive.net/services/v3/TCIA/query/getImage");
        tciaURL = tciaURL + "?SeriesInstanceUID=" + seriesUID;
        tciaURL = tciaURL + "&api_key=" + apiKey;
        log.debug("TCIA Download URL:" + tciaURL);
        HttpClient client = new HttpClient();
        GetMethod method = new GetMethod(tciaURL);
        int statusCode = client.executeMethod(method);
        File uploadStoreDir = new File(EPADConfig.getEPADWebServerUploadDir() + "temp" + System.currentTimeMillis()
                + "_" + seriesUID.substring(seriesUID.length() - 5));
        uploadStoreDir.mkdirs();
        File zipfile = new File(uploadStoreDir, "tcia.zip");
        long total = 0;
        if (statusCode == HttpServletResponse.SC_OK) {
            OutputStream outputStream = null;
            try {
                outputStream = new FileOutputStream(zipfile);
                InputStream inputStream = method.getResponseBodyAsStream();
                int read = 0;
                byte[] bytes = new byte[4096];
                while ((read = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, read);
                    total = total + read;
                }
            } finally {
                IOUtils.closeQuietly(outputStream);
                method.releaseConnection();
            }
            log.debug("TCIA download:" + total + " bytes");
            writePropertiesFile(uploadStoreDir, projectID, "", username);
        } else {
            log.warning("TCIA URL:" + tciaURL + " Status:" + statusCode);
        }
        return statusCode;
    }

    private JsonArray getResponseFromTCIA(String query) throws Exception {
        return getResponseFromTCIA(query, false);
    }

    private JsonArray getResponseFromTCIA(String query, boolean sharedList) throws Exception {
        String tciaURL = EPADConfig.getParamValue(TCIA_URL,
                "https://services.cancerimagingarchive.net/services/v3/TCIA/query/");
        if (sharedList)
            tciaURL = "https://services.cancerimagingarchive.net/services/v3/SharedList/query/";
        tciaURL = tciaURL + query;
        if (tciaURL.indexOf('?') == -1)
            tciaURL = tciaURL + "?";
        else
            tciaURL = tciaURL + "&";
        tciaURL = tciaURL.replace(' ', '+') + "api_key=" + apiKey;
        log.debug("TCIA URL:" + tciaURL);
        Thread.sleep(10000);
        HttpClient client = new HttpClient();
        try {
            GetMethod method = new GetMethod(tciaURL);
            int statusCode = client.executeMethod(method);
            if (statusCode == HttpServletResponse.SC_OK) {
                InputStream is = method.getResponseBodyAsStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                StringBuilder sb = new StringBuilder();

                String line = null;
                try {
                    while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                } catch (IOException e) {
                    log.warning("Error reading response", e);
                    ;
                } finally {
                    try {
                        is.close();
                    } catch (IOException e) {
                    }
                }
                String response = sb.toString();
                log.debug("TCIA response:" + response.length());
                //log.debug("TCIA Response:" + response);
                JsonParser parser = new JsonParser();
                return parser.parse(response).getAsJsonArray();
            } else {
                log.warning("TCIA URL:" + tciaURL + " Status:" + statusCode);
                downtime = System.currentTimeMillis();
                throw new Exception("Error calling TCIA, status = " + statusCode);
            }
        } catch (Exception x) {
            downtime = System.currentTimeMillis();
            log.warning("Error calling TCIA url:" + tciaURL, x);
            throw x;
        }

    }

    // add the properties file xnat_upload.properties.
    private static void writePropertiesFile(File storeDir, String project, String session, String user) {

        String projectName = "XNATProjectName=" + project;
        String sessionName = "XNATSessionID=" + session;
        String userName = "XNATUserName=" + user;

        try {
            File properties = new File(storeDir, "xnat_upload.properties");
            if (!properties.exists()) {
                properties.createNewFile();
            }
            FileOutputStream fop = new FileOutputStream(properties, false);

            fop.write(projectName.getBytes());
            fop.write("\n".getBytes());
            fop.write(sessionName.getBytes());
            fop.write("\n".getBytes());
            fop.write(userName.getBytes());
            fop.write("\n".getBytes());

            fop.flush();
            fop.close();

        } catch (IOException e) {
            log.info("Error writing properties file");
            e.printStackTrace();
        }
    }

    SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMdd");

    private Date getDate(String dateStr) {
        try {
            return dateformat.parse(dateStr);
        } catch (Exception x) {
            return null;
        }
    }
}