# ClinicalTrialIdentificationWorkflow.cs

This is a C# example on how to use gdcm::Anonymizer

    /*=========================================================================

      Program: GDCM (Grassroots DICOM). A DICOM library
      Module:  $URL$

      Copyright (c) 2006-2010 Mathieu Malaterre
      All rights reserved.
      See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.

         This software is distributed WITHOUT ANY WARRANTY; without even
         the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
         PURPOSE.  See the above copyright notice for more information.

    =========================================================================*/
    /*
     * Typical usage on UNIX:
     * $ export LD_LIBRARY_PATH=$HOME/Projects/gdcm/debug-gcc/bin
     * $ mono bin/ClinicalTrialIdentificationWorkflow.exe input_dir output_dir
     */
    using System;
    using gdcm;

    public class MyWatcher : SimpleSubjectWatcher
    {
      public MyWatcher(Subject s):base(s,"Override String"){}
      protected override void StartFilter() {
        System.Console.WriteLine( "This is my start" );
      }
      protected override void EndFilter(){
        System.Console.WriteLine( "This is my end" );
      }
      protected override void ShowProgress(Subject caller, Event evt){
        ProgressEvent pe = ProgressEvent.Cast(evt);
        System.Console.WriteLine( "This is my progress: " + pe.GetProgress() );
      }
      protected override void ShowIteration(){
        System.Console.WriteLine( "This is my iteration" );
      }
      protected override void ShowAnonymization(Subject caller, Event evt){
    /*
     * A couple of explanation are necessary here to understand how SWIG work
     *  http://www.swig.org/Doc1.3/Java.html#adding_downcasts
     *
     *  System.Console.WriteLine( "This is my Anonymization. Type: " + evt.GetEventName() );
     *  System.Type type = evt.GetType();
     *  System.Console.WriteLine( "This is my Anonymization. System.Type: " + type.ToString() );
     *  System.Console.WriteLine( "This is my Anonymization. CheckEvent: " + ae.CheckEvent( evt ) );
     *  System.Console.WriteLine( "This is my Anonymization. Processing Tag #" + ae.GetTag().toString() );
     */
        AnonymizeEvent ae = AnonymizeEvent.Cast(evt);
        if( ae != null )
          {
          Tag t = ae.GetTag();
          System.Console.WriteLine( "This is my Anonymization. Processing Tag #" + t.toString() );
          }
        else
          {
          System.Console.WriteLine( "This is my Anonymization. Unhandled Event type: " + evt.GetEventName() );
          }
      }
      protected override void ShowAbort(){
        System.Console.WriteLine( "This is my abort" );
      }
    }

    public class ClinicalTrialIdentificationWorkflow
    {
      public static bool ProcessOneFile( gdcm.Anonymizer ano , string filename, string outfilename )
        {
        Reader reader = new Reader();
        reader.SetFileName( filename );
        bool ret = reader.Read();
        if( !ret )
          {
          return false;
          }
        // Pass in the file:
        ano.SetFile( reader.GetFile() );

        // First step, let's protect all Patient information as per
        // PS 3.15 / E.1 / Basic Application Level Confidentiality Profile
        if( !ano.BasicApplicationLevelConfidentialityProfile() )
          {
          return false;
          }

        // Now let's pass in all Clinical Trial fields
        // PS 3.3 - 2008 / C.7.1.3 Clinical Trial Subject Module
        /*
        Clinical Trial Sponsor Name (0012,0010) 1 The name of the clinical trial sponsor. See C.7.1.3.1.1.
        Clinical Trial Protocol ID (0012,0020) 1 Identifier for the noted protocol. See C.7.1.3.1.2.
        Clinical Trial Protocol Name (0012,0021) 2 The name of the clinical trial protocol. See C.7.1.3.1.3.
        Clinical Trial Site ID (0012,0030) 2 The identifier of the site responsible for submitting clinical trial data. See C.7.1.3.1.4.
        Clinical Trial Site Name (0012,0031) 2 Name of the site responsible for submitting clinical trial data. See C.7.1.3.1.5
        Clinical Trial Subject ID (0012,0040) 1C The assigned identifier for the clinical trial subject. See C.7.1.3.1.6. Shall be present if Clinical Trial Subject Reading ID (0012,0042) is absent. May be present otherwise.
        Clinical Trial Subject Reading ID (0012,0042) 1C Identifies the subject for blinded evaluations. Shall be present if Clinical Trial Subject ID (0012,0040) is absent.  May be present otherwise. See C.7.1.3.1.7.
         */
        ano.Replace( new gdcm.Tag(0x0012,0x0010), "MySponsorName");
        ano.Replace( new gdcm.Tag(0x0012,0x0020), "MyProtocolID");
        ano.Replace( new gdcm.Tag(0x0012,0x0021), "MyProtocolName");
        ano.Replace( new gdcm.Tag(0x0012,0x0030), "MySiteId");
        ano.Replace( new gdcm.Tag(0x0012,0x0031), "MySiteName");
        ano.Replace( new gdcm.Tag(0x0012,0x0040), "MySponsorId");
        ano.Replace( new gdcm.Tag(0x0012,0x0050), "MyTPId");
        ano.Replace( new gdcm.Tag(0x0012,0x0051), "MyTPDescription");

        // The following two are not required as they are guaranteed to be filled in by the
        // Basic Application Level Confidentiality Profile. Only override if you understand what
        // you are doing
        //ano.Replace( new gdcm.Tag(0x0012,0x0062), "YES");
        //ano.Replace( new gdcm.Tag(0x0012,0x0063), "My Super Duper Anonymization Overload");

        // We might be generating a subdirectory. Let's make sure the subdir exist:
        gdcm.Filename fn = new gdcm.Filename( outfilename );
        string subdir = fn.GetPath();
        if( !gdcm.PosixEmulation.MakeDirectory( subdir ) )
          {
          return false;
          }

        gdcm.FileMetaInformation fmi = ano.GetFile().GetHeader();
        // The following three lines make sure to regenerate any value:
        fmi.Remove( new gdcm.Tag(0x0002,0x0012) );
        fmi.Remove( new gdcm.Tag(0x0002,0x0013) );
        fmi.Remove( new gdcm.Tag(0x0002,0x0016) );

        Writer writer = new Writer();
        writer.SetFileName( outfilename );
        writer.SetFile( ano.GetFile() );
        ret = writer.Write();
        if( !ret )
          {
          return false;
          }

        return true;
        }

      public static int Main(string[] args)
        {
        gdcm.FileMetaInformation.SetSourceApplicationEntityTitle( "My ClinicalTrial App" );

        // http://www.oid-info.com/get/1.3.6.1.4.17434
        string THERALYS_ORG_ROOT = "1.3.6.1.4.17434";
        gdcm.UIDGenerator.SetRoot( THERALYS_ORG_ROOT );
        System.Console.WriteLine( "Root dir is now: " + gdcm.UIDGenerator.GetRoot() );

        gdcm.Global global = gdcm.Global.GetInstance();
        if( !global.LoadResourcesFiles() )
          {
          System.Console.WriteLine( "Could not LoadResourcesFiles" );
          return 1;
          }

        if( args.Length != 2 )
          {
          System.Console.WriteLine( "Usage:" );
          System.Console.WriteLine( "ClinicalTrialIdentificationWorkflow input_dir output_dir" );
          return 1;
          }
        string dir1 = args[0];
        string dir2 = args[1];

        // Check input is valid:
        if( !gdcm.PosixEmulation.FileIsDirectory(dir1) )
          {
          System.Console.WriteLine( "Input directory: " + dir1 + " does not exist. Sorry" );
          return 1;
          }
        if( !gdcm.PosixEmulation.FileIsDirectory(dir2) )
          {
          System.Console.WriteLine( "Output directory: " + dir2 + " does not exist. Sorry" );
          return 1;
          }

        // Recursively search all file within this toplevel directory:
        Directory d = new Directory();
        uint nfiles = d.Load( dir1, true );
        if(nfiles == 0) return 1;

        // Let's use the pre-shipped certificate of GDCM.
        string certpath = gdcm.Filename.Join(gdcm.Testing.GetSourceDirectory(), "/Testing/Source/Data/certificate.pem" );
        gdcm.CryptographicMessageSyntax cms = new gdcm.CryptographicMessageSyntax();
        if( !cms.ParseCertificateFile( certpath ) )
          {
          System.Console.WriteLine( "PEM Certificate : " + certpath + " could not be read. Sorry" );
          return 1;
          }

        //Anonymizer ano = new Anonymizer();
        // A reference to an actual C++ instance is required here:
        SmartPtrAno sano = Anonymizer.New();
        Anonymizer ano = sano.__ref__();

        //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(ano, "Anonymizer");
        MyWatcher watcher = new MyWatcher(ano);

        // Explicitely specify the Cryptographic Message Syntax to use:
        ano.SetCryptographicMessageSyntax( cms );

        // Process all filenames:
        FilenamesType filenames = d.GetFilenames();
        for( uint i = 0; i < nfiles; ++i )
          {
          string filename = filenames[ (int)i ];
          string outfilename = filename.Replace( dir1, dir2 );
          System.Console.WriteLine( "Filename: " + filename );
          System.Console.WriteLine( "Out Filename: " + outfilename );
          if( !ProcessOneFile( ano , filename, outfilename ) )
            {
            System.Console.WriteLine( "Could not process filename: " + filename );
            return 1;
            }
          }

        return 0;
        }
    }