func ReadManifestAndCreateOutput(manifestPath, annotationPath string) (*AnnotationTracker, error) {

	// Fetch any annotations that already exist, or create a file to hold them
	// if none yet do.
	annotations, err := OpenOrCreateAnnotationFile(annotationPath)
	if err != nil {
		return nil, err
	}

	// Now open the full manifest of files we want to critique.
	f, _, err := bulkprocess.MaybeOpenFromGoogleStorage(manifestPath, global.storageClient)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	cr := csv.NewReader(f)
	cr.Comma = '\t'
	recs, err := cr.ReadAll()
	if err != nil {
		return nil, err
	}

	output := make([]ManifestEntry, 0, len(recs))

	header := struct {
		SampleID       int
		Zip            int
		Dicom          int
		Series         int
		InstanceNumber int
	}{}

	for i, cols := range recs {
		if i == 0 {
			for j, col := range cols {
				if col == "zip_file" {
					header.Zip = j
				} else if col == "dicom_file" {
					header.Dicom = j
				} else if col == "series" {
					header.Series = j
				} else if col == "instance_number" {
					header.InstanceNumber = j
				} else if col == "sample_id" {
					header.SampleID = j
				}
			}
			continue
		}

		intInstance, err := strconv.Atoi(cols[header.InstanceNumber])
		if err != nil {
			// Ignore the error
			intInstance = 0
		}

		anno, _ := annotations[DicomFilename(cols[header.Dicom])]

		output = append(output, ManifestEntry{
			SampleID:       cols[header.SampleID],
			Zip:            cols[header.Zip],
			Dicom:          cols[header.Dicom],
			Series:         cols[header.Series],
			InstanceNumber: intInstance,
			Annotation:     anno,
		})
	}

	// For now, don't sort manifests - permits you to arrange them in a preprocessing step
	// sort.Slice(output, generateManifestSorter(output))

	return &AnnotationTracker{Entries: output, AnnotationPath: annotationPath}, nil
}
// ReadManifestAndCreateOutput takes the path to a manifest file and extracts each line. It
// checks to see if the output file has already been created. If so, it reads
// the output and matches it with the manifest, returning pre-populated values.
ReadManifestAndCreateOutput takes the path to a manifest file and extracts each line. It
checks to see if the output file has already been created. If so, it reads
the output and matches it with the manifest, returning pre-populated values.
// ReadManifestAndCreateOutput takes the path to a manifest file and extracts each line . It // checks to see if the output file has already been created . If so it reads // the output and matches it with the manifest returning pre - populated values .
func ReadManifestAndCreateOutput(manifestPath, annotationPath string) (*AnnotationTracker, error) {
	annotations, err := OpenOrCreateAnnotationFile(annotationPath)
	if err != nil {
		return nil, err
	}
	f, _, err := bulkprocess.MaybeOpenFromGoogleStorage(manifestPath, global.storageClient)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	cr := csv.NewReader(f)
	cr.Comma = '\t'
	recs, err := cr.ReadAll()
	if err != nil {
		return nil, err
	}
	output := make([]ManifestEntry, 0, len(recs))
	header := struct {
		SampleID       int
		Zip            int
		Dicom          int
		Series         int
		InstanceNumber int
	}{}
	for i, cols := range recs {
		if i == 0 {
			for j, col := range cols {
				if col == "zip_file" {
					header.Zip = j
				} else if col == "dicom_file" {
					header.Dicom = j
				} else if col == "series" {
					header.Series = j
				} else if col == "instance_number" {
					header.InstanceNumber = j
				} else if col == "sample_id" {
					header.SampleID = j
				}
			}
			continue
		}
		intInstance, err := strconv.Atoi(cols[header.InstanceNumber])
		if err != nil {
			intInstance = 0
		}
		anno, _ := annotations[DicomFilename(cols[header.Dicom])]
		output = append(output, ManifestEntry{
			SampleID:       cols[header.SampleID],
			Zip:            cols[header.Zip],
			Dicom:          cols[header.Dicom],
			Series:         cols[header.Series],
			InstanceNumber: intInstance,
			Annotation:     anno,
		})
	}
	return &AnnotationTracker{Entries: output, AnnotationPath: annotationPath}, nil
}
func ReadManifestAndCreateOutput ( manifestPath , annotationPath string ) ( * AnnotationTracker , error ) { annotations , err := OpenOrCreateAnnotationFile ( annotationPath ) if err != nil { return nil , err } f , _ , err := bulkprocess . MaybeOpenFromGoogleStorage ( manifestPath , global . storageClient ) if err != nil { return nil , err } defer f . Close ( ) cr := csv . NewReader ( f ) cr . Comma = '\t' recs , err := cr . ReadAll ( ) if err != nil { return nil , err } output := make ( [ ] ManifestEntry , 0 , len ( recs ) ) header := struct { SampleID int Zip int Dicom int Series int InstanceNumber int } { } for i , cols := range recs { if i == 0 { for j , col := range cols { if col == " " { header . Zip = j } else if col == " " { header . Dicom = j } else if col == " " { header . Series = j } else if col == " " { header . InstanceNumber = j } else if col == " " { header . SampleID = j } } continue } intInstance , err := strconv . Atoi ( cols [ header . InstanceNumber ] ) if err != nil { intInstance = 0 } anno , _ := annotations [ DicomFilename ( cols [ header . Dicom ] ) ] output = append ( output , ManifestEntry { SampleID : cols [ header . SampleID ] , Zip : cols [ header . Zip ] , Dicom : cols [ header . Dicom ] , Series : cols [ header . Series ] , InstanceNumber : intInstance , Annotation : anno , } ) } return & AnnotationTracker { Entries : output , AnnotationPath : annotationPath } , nil }
ReadManifestAndCreateOutput takes the path to a manifest file and extracts each line.
ReadManifestAndCreateOutput takes the path to a manifest file and extracts each line .
// Fetch any annotations that already exist, or create a file to hold them // if none yet do. // Now open the full manifest of files we want to critique. // Ignore the error // For now, don't sort manifests - permits you to arrange them in a preprocessing step // sort.Slice(output, generateManifestSorter(output))