diff --git a/AttentiveChrome/README.md b/AttentiveChrome/README.md new file mode 100644 index 000000000..543671abb --- /dev/null +++ b/AttentiveChrome/README.md @@ -0,0 +1,62 @@ +# Attentive Chrome Kipoi + +## Dependency Requirements +* python>=3.5 +* numpy +* pytorch-cpu +* torchvision-cpu + +## Quick Start +### Creating new conda environtment using kipoi +`kipoi env create AttentiveChrome` + +### Activating environment +`conda activate kipoi-AttentiveChrome` + +## Command Line +### Getting example input file +Replace {model_name} with the actual name of model (e.g. E003, E005, etc.) + +`kipoi get-example AttentiveChrome/{model_name} -o example_file` + +example: `kipoi get-example AttentiveChrome/E003 -o example_file` + +### Predicting using example file +`kipoi predict AttentiveChrome/{model_name} --dataloader_args='{"input_file": "example_file/input_file", "bin_size": 100}' -o example_predict.tsv` + +This should produce a tsv file containing the results. + +## Python +### Fetching the model +First, import kipoi: +`import kipoi` + +Next, get the model. Replace {model_name} with the actual name of model (e.g. E003, E005, etc.) + +`model = kipoi.get_model("AttentiveChrome/{model_name}")` + +### Predicting using pipeline +`prediction = model.pipeline.predict({"input_file": "path to input file", "bin_size": {some integer}})` + +This returns a numpy array containing the output from the final softmax function. + +e.g. `model.pipeline.predict({"input_file": "data/input_file", "bin_size": 100})` + +### Predicting for a single batch +First, we need to set up our dataloader `dl`. + +`dl = model.default_dataloader(input_file="path to input file", bin_size={some integer})` + +Next, we can use the iterator functionality of the dataloader. + +`it = dl.batch_iter(batch_size=32)` + +`single_batch = next(it)` + +First line gets us an iterator named `it` with each batch containing 32 items. We can use `next(it)` to get a batch. + +Then, we can perform prediction on this single batch. + +`prediction = model.predict_on_batch(single_batch['inputs'])` + +This also returns a numpy array containing the output from the final softmax function. diff --git a/AttentiveChrome/dataloader.py b/AttentiveChrome/dataloader.py new file mode 100644 index 000000000..8cd6644ac --- /dev/null +++ b/AttentiveChrome/dataloader.py @@ -0,0 +1,77 @@ +import torch +import collections +import pdb +import csv +from kipoi.data import Dataset +import math +import numpy as np + +class HMData(Dataset): + # Dataset class for loading data + def __init__(self, input_file, bin_size=100): + self.hm_data = self.loadData(input_file, bin_size) + + + def loadData(self,filename,windows): + with open(filename) as fi: + csv_reader=csv.reader(fi) + data=list(csv_reader) + + ncols=(len(data[0])) + fi.close() + nrows=len(data) + ngenes=nrows/windows + nfeatures=ncols-1 + print("Number of genes: %d" % ngenes) + print("Number of entries: %d" % nrows) + print("Number of HMs: %d" % nfeatures) + + count=0 + attr=collections.OrderedDict() + + for i in range(0,nrows,windows): + hm1=torch.zeros(windows,1) + hm2=torch.zeros(windows,1) + hm3=torch.zeros(windows,1) + hm4=torch.zeros(windows,1) + hm5=torch.zeros(windows,1) + for w in range(0,windows): + hm1[w][0]=int(data[i+w][2]) + hm2[w][0]=int(data[i+w][3]) + hm3[w][0]=int(data[i+w][4]) + hm4[w][0]=int(data[i+w][5]) + hm5[w][0]=int(data[i+w][6]) + geneID=str(data[i][0].split("_")[0]) + + thresholded_expr = int(data[i+w][7]) + + attr[count]={ + 'geneID':geneID, + 'expr':thresholded_expr, + 'hm1':hm1, + 'hm2':hm2, + 'hm3':hm3, + 'hm4':hm4, + 'hm5':hm5 + } + count+=1 + + return attr + + + def __len__(self): + return len(self.hm_data) + + def __getitem__(self,i): + final_data=torch.cat((self.hm_data[i]['hm1'],self.hm_data[i]['hm2'],self.hm_data[i]['hm3'],self.hm_data[i]['hm4'],self.hm_data[i]['hm5']),1) + final_data = final_data.numpy() + label = self.hm_data[i]['expr'] + geneID = self.hm_data[i]['geneID'] + + + return_item={ + 'inputs': final_data, + 'metadata': {'geneID':geneID,'label':label} + } + + return return_item diff --git a/AttentiveChrome/dataloader.yaml b/AttentiveChrome/dataloader.yaml new file mode 100644 index 000000000..13cc5f880 --- /dev/null +++ b/AttentiveChrome/dataloader.yaml @@ -0,0 +1,48 @@ +defined_as: dataloader.HMData +args: + input_file: + doc: "Path of the histone modification read count file." + example: + url: https://zenodo.org/record/2640883/files/test.csv?download=1 + md5: 0468f46aa1a3864283e87c7714d0a4e2 + bin_size: + doc: "Size of bin" + optional: true +dependencies: + conda: # install via conda + - python>=3.5 + - pytorch::pytorch-cpu + - numpy +info: # General information about the dataloader + authors: + - name: Ritambhara Singh + github: rs3zz + - name: Jack Lanchantin + github: jacklanchantin + email: jjl5sw@virginia.edu + - name: Arshdeep Sekhon + github: ArshdeepSekhon + - name: Yanjun Qi + github: qiyanjun + contributors: + - name: Jack Lanchantin + github: jacklanchantin + - name: Jeffrey Yoo + github: jeffreyyoo + doc: "Dataloader for Gene Expression Prediction" + cite_as: https://doi.org:/10.1101/329334 + trained_on: Histone Modidification and RNA Seq Data From Roadmad/REMC database # short dataset description + license: MIT +output_schema: + inputs: + associated_metadata: geneID, label + doc: Histone Modification Bin Matrix + shape: (100, 5) # array shape of a single sample (omitting the batch dimension) + metadata: + geneID: + doc: "gene ID" + type: str + label: + doc: "label for gene expression (binary)" + type: int +type: Dataset diff --git a/AttentiveChrome/model-template.yaml b/AttentiveChrome/model-template.yaml new file mode 100755 index 000000000..9b9913601 --- /dev/null +++ b/AttentiveChrome/model-template.yaml @@ -0,0 +1,42 @@ +type: pytorch +args: + module_file: models.py + module_obj: att_chrome_model + weights: + url: {{model_url}} + md5: {{model_md5}} +default_dataloader: .. # path to the dataloader directory. Or to the dataloader class, e.g.: `kipoiseq.dataloaders.SeqIntervalDl + +info: # General information about the model + authors: + - name: Ritambhara Singh + github: rs3zz + - name: Jack Lanchantin + github: jacklanchantin + email: jjl5sw@virginia.edu + - name: Arshdeep Sekhon + github: ArshdeepSekhon + - name: Yanjun Qi + github: qiyanjun + contributors: + - name: Jack Lanchantin + github: jacklanchantin + - name: Jeffrey Yoo + github: jeffreyyoo + doc: Gene Expression Prediction + cite_as: https://doi.org:/10.1101/329334 + trained_on: Histone Modidification and RNA Seq Data From Roadmad/REMC database # short dataset description + license: MIT +dependencies: + conda: # install via conda + - python>=3.5 + - numpy + - pytorch::pytorch-cpu + - pytorch::torchvision-cpu +schema: # Model schema + inputs: + shape: (100, 5) # array shape of a single sample (omitting the batch dimension) + doc: "Histone Modification Bin Matrix" + targets: + shape: (1, ) + doc: "Binary Classification" diff --git a/AttentiveChrome/models.py b/AttentiveChrome/models.py new file mode 100755 index 000000000..b4a0c4c91 --- /dev/null +++ b/AttentiveChrome/models.py @@ -0,0 +1,122 @@ +from __future__ import print_function +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +from pdb import set_trace as stop + +def batch_product(iput, mat2): + result = None + for i in range(iput.size()[0]): + op = torch.mm(iput[i], mat2) + op = op.unsqueeze(0) + if(result is None): + result = op + else: + result = torch.cat((result,op),0) + return result.squeeze(2) + + +class rec_attention(nn.Module): + # attention with bin context vector per HM and HM context vector + def __init__(self,hm,args): + super(rec_attention,self).__init__() + self.num_directions=2 if args.bidirectional else 1 + if (hm==False): + self.bin_rep_size=args.bin_rnn_size*self.num_directions + else: + self.bin_rep_size=args.bin_rnn_size + + self.bin_context_vector=nn.Parameter(torch.Tensor(self.bin_rep_size,1),requires_grad=True) + + + self.softmax=nn.Softmax(dim=1) + + self.bin_context_vector.data.uniform_(-0.1, 0.1) + + def forward(self,iput): + alpha=self.softmax(batch_product(iput,self.bin_context_vector)) + [batch_size,source_length,bin_rep_size2]=iput.size() + repres=torch.bmm(alpha.unsqueeze(2).view(batch_size,-1,source_length),iput) + return repres,alpha + + + +class recurrent_encoder(nn.Module): + # modular LSTM encoder + def __init__(self,n_bins,ip_bin_size,hm,args): + super(recurrent_encoder,self).__init__() + self.bin_rnn_size=args.bin_rnn_size + self.ipsize=ip_bin_size + self.seq_length=n_bins + + self.num_directions=2 if args.bidirectional else 1 + if (hm==False): + self.bin_rnn_size=args.bin_rnn_size + else: + self.bin_rnn_size=args.bin_rnn_size // 2 + self.bin_rep_size=self.bin_rnn_size*self.num_directions + + + self.rnn=nn.LSTM(self.ipsize,self.bin_rnn_size,num_layers=args.num_layers,dropout=args.dropout,bidirectional=args.bidirectional) + + self.bin_attention=rec_attention(hm,args) + def outputlength(self): + return self.bin_rep_size + def forward(self,single_hm,hidden=None): + bin_output, hidden = self.rnn(single_hm,hidden) + bin_output = bin_output.permute(1,0,2) + hm_rep,bin_alpha = self.bin_attention(bin_output) + return hm_rep,bin_alpha + + +class AttrDict(dict): + def __init__(self, *args, **kwargs): + super(AttrDict, self).__init__(*args, **kwargs) + self.__dict__ = self + + +class att_chrome(nn.Module): + def __init__(self,args): + super(att_chrome,self).__init__() + self.n_hms=args.n_hms + self.n_bins=args.n_bins + self.ip_bin_size=1 + + self.rnn_hms=nn.ModuleList() + for i in range(self.n_hms): + self.rnn_hms.append(recurrent_encoder(self.n_bins,self.ip_bin_size,False,args)) + self.opsize = self.rnn_hms[0].outputlength() + self.hm_level_rnn_1=recurrent_encoder(self.n_hms,self.opsize,True,args) + self.opsize2=self.hm_level_rnn_1.outputlength() + self.diffopsize=2*(self.opsize2) + self.fdiff1_1=nn.Linear(self.opsize2,1) + + def forward(self,iput): + + bin_a=None + level1_rep=None + [batch_size,_,_]=iput.size() + + for hm,hm_encdr in enumerate(self.rnn_hms): + hmod=iput[:,:,hm].contiguous() + hmod=torch.t(hmod).unsqueeze(2) + + op,a= hm_encdr(hmod) + if level1_rep is None: + level1_rep=op + bin_a=a + else: + level1_rep=torch.cat((level1_rep,op),1) + bin_a=torch.cat((bin_a,a),1) + level1_rep=level1_rep.permute(1,0,2) + final_rep_1,hm_level_attention_1=self.hm_level_rnn_1(level1_rep) + final_rep_1=final_rep_1.squeeze(1) + prediction_m=((self.fdiff1_1(final_rep_1))) + + return torch.sigmoid(prediction_m) + +args_dict = {'lr': 0.0001, 'model_name': 'attchrome', 'clip': 1, 'epochs': 2, 'batch_size': 10, 'dropout': 0.5, 'cell_1': 'Cell1', 'save_root': 'Results/Cell1', 'data_root': 'data/', 'gpuid': 0, 'gpu': 0, 'n_hms': 5, 'n_bins': 200, 'bin_rnn_size': 32, 'num_layers': 1, 'unidirectional': False, 'save_attention_maps': False, 'attentionfilename': 'beta_attention.txt', 'test_on_saved_model': False, 'bidirectional': True, 'dataset': 'Cell1'} +att_chrome_args = AttrDict(args_dict) +att_chrome_model = att_chrome(att_chrome_args) + diff --git a/AttentiveChrome/models.tsv b/AttentiveChrome/models.tsv new file mode 100644 index 000000000..b3b991889 --- /dev/null +++ b/AttentiveChrome/models.tsv @@ -0,0 +1,56 @@ +model model_url model_md5 +E003 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E003_attchrome_avgAUC_model.pt?download=1 9b4ff730ac5e70265f7a78162fa76768 +E004 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E004_attchrome_avgAUC_model.pt?download=1 36edb7c1561bf26c29ebbd72fae9e6a2 +E005 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E005_attchrome_avgAUC_model.pt?download=1 19f61dca439ffcf7bbe44ca15238ff4d +E006 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E006_attchrome_avgAUC_model.pt?download=1 6bf8b66481a97a3b8b1f6c019432a1e0 +E007 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E007_attchrome_avgAUC_model.pt?download=1 da2104816feafbf1a2567af71a9be2d8 +E011 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E011_attchrome_avgAUC_model.pt?download=1 51b455dbe695e3e059162c8154b09a74 +E012 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E012_attchrome_avgAUC_model.pt?download=1 a0359c3462a8bbee23fb11e3ada5c43a +E013 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E013_attchrome_avgAUC_model.pt?download=1 1ca6c07c12773d6c69052959d6807ddc +E016 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E016_attchrome_avgAUC_model.pt?download=1 25e8e91376dfecca41087d4560c3e9ee +E024 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E024_attchrome_avgAUC_model.pt?download=1 34f1c4de69988560f63d983daf35a05f +E027 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E027_attchrome_avgAUC_model.pt?download=1 a878a845467287d8e9d821ed44c5ad93 +E028 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E028_attchrome_avgAUC_model.pt?download=1 ad019b35a52fae8971df9790eb70e050 +E037 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E037_attchrome_avgAUC_model.pt?download=1 45e32e1ab02692ad529de480761329de +E038 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E038_attchrome_avgAUC_model.pt?download=1 39036cd5afa8fc95222f88c2c9ad2ee6 +E047 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E047_attchrome_avgAUC_model.pt?download=1 5428bbb213fb90e47205a753e7820aef +E050 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E050_attchrome_avgAUC_model.pt?download=1 e2b2edf9cf44d0c892b5619fc537ce57 +E053 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E053_attchrome_avgAUC_model.pt?download=1 5237ab0e405298e1fd616f57bbdcd8d7 +E054 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E054_attchrome_avgAUC_model.pt?download=1 1fd0ccc28e1c204574763a6dbb3e6c77 +E055 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E055_attchrome_avgAUC_model.pt?download=1 f7f6dff85b274ee77179095c97421167 +E056 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E056_attchrome_avgAUC_model.pt?download=1 93fdbc651eb966a94298a0c1d3452b8b +E057 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E057_attchrome_avgAUC_model.pt?download=1 37176c4f55a477e4d661ddcb8ac4a063 +E058 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E058_attchrome_avgAUC_model.pt?download=1 a84d022064081663cdeba823e3d82d28 +E061 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E061_attchrome_avgAUC_model.pt?download=1 0f777b410ade532bba4d0b90e827bb31 +E062 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E062_attchrome_avgAUC_model.pt?download=1 f29133dd6809c451dfe94e9a8dfebe18 +E065 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E065_attchrome_avgAUC_model.pt?download=1 c29295513ed0af1f038be4d1a2846fe5 +E066 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E066_attchrome_avgAUC_model.pt?download=1 2e6ddfc87be8e2a1f86b6fc22a32c228 +E070 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E070_attchrome_avgAUC_model.pt?download=1 f164f58f1965b3bd61eb5ae04a57def5 +E071 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E071_attchrome_avgAUC_model.pt?download=1 333566e947e04a9dfdc543b6c489b1c3 +E079 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E079_attchrome_avgAUC_model.pt?download=1 978c928625b8027bad8898c7aeac622b +E082 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E082_attchrome_avgAUC_model.pt?download=1 8b9d27c361c1ad258bde428fa72c8980 +E084 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E084_attchrome_avgAUC_model.pt?download=1 c0c1009fe4febfbf7dc64406466d8459 +E085 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E085_attchrome_avgAUC_model.pt?download=1 452ae1b368bf7b37d38ec89db51e463f +E087 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E087_attchrome_avgAUC_model.pt?download=1 22137bd5dc6bdb78bdde944297c4ec54 +E094 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E094_attchrome_avgAUC_model.pt?download=1 f83430563d10c76f0396ed5574bee820 +E095 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E095_attchrome_avgAUC_model.pt?download=1 37130b60530f29aaf485a9789c905a2e +E096 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E096_attchrome_avgAUC_model.pt?download=1 2be0fa577637386851bba657d6af60b5 +E097 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E097_attchrome_avgAUC_model.pt?download=1 97d266de1fce0c207d141126ff5cb143 +E098 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E098_attchrome_avgAUC_model.pt?download=1 8b40090f6217e0c252f56f92c5719a74 +E100 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E100_attchrome_avgAUC_model.pt?download=1 89867aede18576cf245501be1b66de3c +E104 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E104_attchrome_avgAUC_model.pt?download=1 6d7defac37ffaf3bec204f76892eb2f2 +E105 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E105_attchrome_avgAUC_model.pt?download=1 c773aac4b33885e6f69f0241a2b84931 +E106 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E106_attchrome_avgAUC_model.pt?download=1 5d73011e3345e5d998d81169a8ea28c1 +E109 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E109_attchrome_avgAUC_model.pt?download=1 689f51758a873d0c99d32e5e8c80513b +E112 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E112_attchrome_avgAUC_model.pt?download=1 a671823c56b8b4e000baec18562540aa +E113 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E113_attchrome_avgAUC_model.pt?download=1 586b6c6c003a7c919fde57d2be0f5180 +E114 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E114_attchrome_avgAUC_model.pt?download=1 5ca9959f7442342907c2c5f0bc26d73b +E116 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E116_attchrome_avgAUC_model.pt?download=1 ecdeb5d30b6124b0bce0d5e45046cab9 +E117 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E117_attchrome_avgAUC_model.pt?download=1 11be77c7266b198ee3f2fc74e452395c +E118 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E118_attchrome_avgAUC_model.pt?download=1 65bd6369cddb01a837910694b84d00a6 +E119 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E119_attchrome_avgAUC_model.pt?download=1 ea3e5d604a4b69c3b26066e5d23dfe12 +E120 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E120_attchrome_avgAUC_model.pt?download=1 98beb529d183c7b0d3ce661699a4d6aa +E122 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E122_attchrome_avgAUC_model.pt?download=1 eb26f18e6458bc4053c2dbdd1a95c6ac +E123 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E123_attchrome_avgAUC_model.pt?download=1 dae6687bc9e6ac27945c176a9cacc9cc +E127 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E127_attchrome_avgAUC_model.pt?download=1 9536df4e7822b0a14d2d50c451f47b1f +E128 https://zenodo.org/api/files/2bf982b6-143f-49f6-b9ad-1b1e60f67292/E128_attchrome_avgAUC_model.pt?download=1 458eb929a4691faad12a274e2c727f50 diff --git a/AttentiveChrome/test_subset.txt b/AttentiveChrome/test_subset.txt new file mode 100644 index 000000000..e8b2dabae --- /dev/null +++ b/AttentiveChrome/test_subset.txt @@ -0,0 +1 @@ +E003